From 64cea3e2381966ac276a50361e384b5f0a5198bf Mon Sep 17 00:00:00 2001 From: Owl Bot Date: Thu, 7 Sep 2023 17:00:38 +0000 Subject: [PATCH] docs: Minor formatting chore: Update gapic-generator-python to v1.11.5 build: Update rules_python to 0.24.0 PiperOrigin-RevId: 563436317 Source-Link: https://github.com/googleapis/googleapis/commit/42fd37b18d706f6f51f52f209973b3b2c28f509a Source-Link: https://github.com/googleapis/googleapis-gen/commit/280264ca02fb9316b4237a96d0af1a2343a81a56 Copy-Tag: eyJwIjoiLmdpdGh1Yi8uT3dsQm90LnlhbWwiLCJoIjoiMjgwMjY0Y2EwMmZiOTMxNmI0MjM3YTk2ZDBhZjFhMjM0M2E4MWE1NiJ9 --- owl-bot-staging/v2/.coveragerc | 13 + owl-bot-staging/v2/.flake8 | 33 + owl-bot-staging/v2/MANIFEST.in | 2 + owl-bot-staging/v2/README.rst | 49 + owl-bot-staging/v2/docs/_static/custom.css | 3 + owl-bot-staging/v2/docs/conf.py | 376 + owl-bot-staging/v2/docs/index.rst | 7 + .../v2/docs/retail_v2/catalog_service.rst | 10 + .../v2/docs/retail_v2/completion_service.rst | 6 + .../v2/docs/retail_v2/control_service.rst | 10 + .../v2/docs/retail_v2/model_service.rst | 10 + .../v2/docs/retail_v2/prediction_service.rst | 6 + .../v2/docs/retail_v2/product_service.rst | 10 + .../v2/docs/retail_v2/search_service.rst | 10 + .../v2/docs/retail_v2/services.rst | 14 + .../docs/retail_v2/serving_config_service.rst | 10 + owl-bot-staging/v2/docs/retail_v2/types.rst | 6 + .../v2/docs/retail_v2/user_event_service.rst | 6 + .../v2/google/cloud/retail/__init__.py | 301 + .../v2/google/cloud/retail/gapic_version.py | 16 + .../v2/google/cloud/retail/py.typed | 2 + .../v2/google/cloud/retail_v2/__init__.py | 302 + .../cloud/retail_v2/gapic_metadata.json | 945 ++ .../google/cloud/retail_v2/gapic_version.py | 16 + .../v2/google/cloud/retail_v2/py.typed | 2 + .../cloud/retail_v2/services/__init__.py | 15 + .../services/catalog_service/__init__.py | 22 + .../services/catalog_service/async_client.py | 1522 +++ .../services/catalog_service/client.py | 1759 ++++ .../services/catalog_service/pagers.py | 140 + .../catalog_service/transports/__init__.py | 38 + .../catalog_service/transports/base.py | 311 + .../catalog_service/transports/grpc.py | 635 ++ .../transports/grpc_asyncio.py | 634 ++ .../catalog_service/transports/rest.py | 1638 +++ .../services/completion_service/__init__.py | 22 + .../completion_service/async_client.py | 507 + .../services/completion_service/client.py | 716 ++ .../completion_service/transports/__init__.py | 38 + .../completion_service/transports/base.py | 189 + .../completion_service/transports/grpc.py | 366 + .../transports/grpc_asyncio.py | 365 + .../completion_service/transports/rest.py | 666 ++ .../services/control_service/__init__.py | 22 + .../services/control_service/async_client.py | 874 ++ .../services/control_service/client.py | 1090 ++ .../services/control_service/pagers.py | 140 + .../control_service/transports/__init__.py | 38 + .../control_service/transports/base.py | 227 + .../control_service/transports/grpc.py | 421 + .../transports/grpc_asyncio.py | 420 + .../control_service/transports/rest.py | 930 ++ .../services/model_service/__init__.py | 22 + .../services/model_service/async_client.py | 1218 +++ .../services/model_service/client.py | 1434 +++ .../services/model_service/pagers.py | 140 + .../model_service/transports/__init__.py | 38 + .../services/model_service/transports/base.py | 275 + .../services/model_service/transports/grpc.py | 518 + .../model_service/transports/grpc_asyncio.py | 517 + .../services/model_service/transports/rest.py | 1378 +++ .../services/prediction_service/__init__.py | 22 + .../prediction_service/async_client.py | 384 + .../services/prediction_service/client.py | 592 ++ .../prediction_service/transports/__init__.py | 38 + .../prediction_service/transports/base.py | 168 + .../prediction_service/transports/grpc.py | 302 + .../transports/grpc_asyncio.py | 301 + .../prediction_service/transports/rest.py | 495 + .../services/product_service/__init__.py | 22 + .../services/product_service/async_client.py | 1939 ++++ .../services/product_service/client.py | 2149 ++++ .../services/product_service/pagers.py | 140 + .../product_service/transports/__init__.py | 38 + .../product_service/transports/base.py | 325 + .../product_service/transports/grpc.py | 764 ++ .../transports/grpc_asyncio.py | 763 ++ .../product_service/transports/rest.py | 1731 ++++ .../services/search_service/__init__.py | 22 + .../services/search_service/async_client.py | 414 + .../services/search_service/client.py | 649 ++ .../services/search_service/pagers.py | 139 + .../search_service/transports/__init__.py | 38 + .../search_service/transports/base.py | 168 + .../search_service/transports/grpc.py | 310 + .../search_service/transports/grpc_asyncio.py | 309 + .../search_service/transports/rest.py | 504 + .../serving_config_service/__init__.py | 22 + .../serving_config_service/async_client.py | 1098 ++ .../services/serving_config_service/client.py | 1314 +++ .../services/serving_config_service/pagers.py | 140 + .../transports/__init__.py | 38 + .../serving_config_service/transports/base.py | 255 + .../serving_config_service/transports/grpc.py | 480 + .../transports/grpc_asyncio.py | 479 + .../serving_config_service/transports/rest.py | 1182 +++ .../services/user_event_service/__init__.py | 22 + .../user_event_service/async_client.py | 865 ++ .../services/user_event_service/client.py | 1072 ++ .../user_event_service/transports/__init__.py | 38 + .../user_event_service/transports/base.py | 248 + .../user_event_service/transports/grpc.py | 455 + .../transports/grpc_asyncio.py | 454 + .../user_event_service/transports/rest.py | 1082 ++ .../google/cloud/retail_v2/types/__init__.py | 298 + .../google/cloud/retail_v2/types/catalog.py | 539 + .../cloud/retail_v2/types/catalog_service.py | 457 + .../v2/google/cloud/retail_v2/types/common.py | 1255 +++ .../retail_v2/types/completion_service.py | 251 + .../google/cloud/retail_v2/types/control.py | 116 + .../cloud/retail_v2/types/control_service.py | 200 + .../cloud/retail_v2/types/import_config.py | 702 ++ .../v2/google/cloud/retail_v2/types/model.py | 320 + .../cloud/retail_v2/types/model_service.py | 274 + .../retail_v2/types/prediction_service.py | 297 + .../google/cloud/retail_v2/types/product.py | 796 ++ .../cloud/retail_v2/types/product_service.py | 889 ++ .../google/cloud/retail_v2/types/promotion.py | 54 + .../cloud/retail_v2/types/purge_config.py | 111 + .../cloud/retail_v2/types/search_service.py | 1410 +++ .../cloud/retail_v2/types/serving_config.py | 357 + .../retail_v2/types/serving_config_service.py | 238 + .../cloud/retail_v2/types/user_event.py | 524 + .../retail_v2/types/user_event_service.py | 203 + owl-bot-staging/v2/mypy.ini | 3 + owl-bot-staging/v2/noxfile.py | 184 + ...log_service_add_catalog_attribute_async.py | 56 + ...alog_service_add_catalog_attribute_sync.py | 56 + ...log_service_get_attributes_config_async.py | 52 + ...alog_service_get_attributes_config_sync.py | 52 + ...log_service_get_completion_config_async.py | 52 + ...alog_service_get_completion_config_sync.py | 52 + ...atalog_service_get_default_branch_async.py | 51 + ...catalog_service_get_default_branch_sync.py | 51 + ...ted_catalog_service_list_catalogs_async.py | 53 + ...ated_catalog_service_list_catalogs_sync.py | 53 + ..._service_remove_catalog_attribute_async.py | 53 + ...g_service_remove_catalog_attribute_sync.py | 53 + ...service_replace_catalog_attribute_async.py | 56 + ..._service_replace_catalog_attribute_sync.py | 56 + ...atalog_service_set_default_branch_async.py | 49 + ...catalog_service_set_default_branch_sync.py | 49 + ..._service_update_attributes_config_async.py | 55 + ...g_service_update_attributes_config_sync.py | 55 + ...ed_catalog_service_update_catalog_async.py | 56 + ...ted_catalog_service_update_catalog_sync.py | 56 + ..._service_update_completion_config_async.py | 55 + ...g_service_update_completion_config_sync.py | 55 + ...completion_service_complete_query_async.py | 53 + ..._completion_service_complete_query_sync.py | 53 + ...on_service_import_completion_data_async.py | 61 + ...ion_service_import_completion_data_sync.py | 61 + ...ed_control_service_create_control_async.py | 58 + ...ted_control_service_create_control_sync.py | 58 + ...ed_control_service_delete_control_async.py | 50 + ...ted_control_service_delete_control_sync.py | 50 + ...rated_control_service_get_control_async.py | 52 + ...erated_control_service_get_control_sync.py | 52 + ...ted_control_service_list_controls_async.py | 53 + ...ated_control_service_list_controls_sync.py | 53 + ...ed_control_service_update_control_async.py | 56 + ...ted_control_service_update_control_sync.py | 56 + ...erated_model_service_create_model_async.py | 62 + ...nerated_model_service_create_model_sync.py | 62 + ...erated_model_service_delete_model_async.py | 50 + ...nerated_model_service_delete_model_sync.py | 50 + ...generated_model_service_get_model_async.py | 52 + ..._generated_model_service_get_model_sync.py | 52 + ...nerated_model_service_list_models_async.py | 53 + ...enerated_model_service_list_models_sync.py | 53 + ...nerated_model_service_pause_model_async.py | 52 + ...enerated_model_service_pause_model_sync.py | 52 + ...erated_model_service_resume_model_async.py | 52 + ...nerated_model_service_resume_model_sync.py | 52 + ...enerated_model_service_tune_model_async.py | 56 + ...generated_model_service_tune_model_sync.py | 56 + ...erated_model_service_update_model_async.py | 57 + ...nerated_model_service_update_model_sync.py | 57 + ...erated_prediction_service_predict_async.py | 57 + ...nerated_prediction_service_predict_sync.py | 57 + ...ct_service_add_fulfillment_places_async.py | 58 + ...uct_service_add_fulfillment_places_sync.py | 58 + ...uct_service_add_local_inventories_async.py | 56 + ...duct_service_add_local_inventories_sync.py | 56 + ...ed_product_service_create_product_async.py | 57 + ...ted_product_service_create_product_sync.py | 57 + ...ed_product_service_delete_product_async.py | 50 + ...ted_product_service_delete_product_sync.py | 50 + ...rated_product_service_get_product_async.py | 52 + ...erated_product_service_get_product_sync.py | 52 + ...d_product_service_import_products_async.py | 60 + ...ed_product_service_import_products_sync.py | 60 + ...ted_product_service_list_products_async.py | 53 + ...ated_product_service_list_products_sync.py | 53 + ...service_remove_fulfillment_places_async.py | 58 + ..._service_remove_fulfillment_places_sync.py | 58 + ..._service_remove_local_inventories_async.py | 57 + ...t_service_remove_local_inventories_sync.py | 57 + ...ted_product_service_set_inventory_async.py | 59 + ...ated_product_service_set_inventory_sync.py | 59 + ...ed_product_service_update_product_async.py | 55 + ...ted_product_service_update_product_sync.py | 55 + ...2_generated_search_service_search_async.py | 54 + ...v2_generated_search_service_search_sync.py | 54 + ...erving_config_service_add_control_async.py | 53 + ...serving_config_service_add_control_sync.py | 53 + ...fig_service_create_serving_config_async.py | 58 + ...nfig_service_create_serving_config_sync.py | 58 + ...fig_service_delete_serving_config_async.py | 50 + ...nfig_service_delete_serving_config_sync.py | 50 + ...config_service_get_serving_config_async.py | 52 + ..._config_service_get_serving_config_sync.py | 52 + ...nfig_service_list_serving_configs_async.py | 53 + ...onfig_service_list_serving_configs_sync.py | 53 + ...ing_config_service_remove_control_async.py | 53 + ...ving_config_service_remove_control_sync.py | 53 + ...fig_service_update_serving_config_async.py | 56 + ...nfig_service_update_serving_config_sync.py | 56 + ..._event_service_collect_user_event_async.py | 54 + ...r_event_service_collect_user_event_sync.py | 54 + ..._event_service_import_user_events_async.py | 61 + ...r_event_service_import_user_events_sync.py | 61 + ...r_event_service_purge_user_events_async.py | 57 + ...er_event_service_purge_user_events_sync.py | 57 + ..._event_service_rejoin_user_events_async.py | 56 + ...r_event_service_rejoin_user_events_sync.py | 56 + ...er_event_service_write_user_event_async.py | 57 + ...ser_event_service_write_user_event_sync.py | 57 + ...ippet_metadata_google.cloud.retail.v2.json | 8212 +++++++++++++++ .../v2/scripts/fixup_retail_v2_keywords.py | 226 + owl-bot-staging/v2/setup.py | 90 + .../v2/testing/constraints-3.10.txt | 6 + .../v2/testing/constraints-3.11.txt | 6 + .../v2/testing/constraints-3.12.txt | 6 + .../v2/testing/constraints-3.7.txt | 9 + .../v2/testing/constraints-3.8.txt | 6 + .../v2/testing/constraints-3.9.txt | 6 + owl-bot-staging/v2/tests/__init__.py | 16 + owl-bot-staging/v2/tests/unit/__init__.py | 16 + .../v2/tests/unit/gapic/__init__.py | 16 + .../v2/tests/unit/gapic/retail_v2/__init__.py | 16 + .../gapic/retail_v2/test_catalog_service.py | 6646 ++++++++++++ .../retail_v2/test_completion_service.py | 2307 +++++ .../gapic/retail_v2/test_control_service.py | 4300 ++++++++ .../gapic/retail_v2/test_model_service.py | 5874 +++++++++++ .../retail_v2/test_prediction_service.py | 1931 ++++ .../gapic/retail_v2/test_product_service.py | 7266 +++++++++++++ .../gapic/retail_v2/test_search_service.py | 2263 +++++ .../retail_v2/test_serving_config_service.py | 5655 +++++++++++ .../retail_v2/test_user_event_service.py | 3431 +++++++ owl-bot-staging/v2alpha/.coveragerc | 13 + owl-bot-staging/v2alpha/.flake8 | 33 + owl-bot-staging/v2alpha/MANIFEST.in | 2 + owl-bot-staging/v2alpha/README.rst | 49 + .../v2alpha/docs/_static/custom.css | 3 + owl-bot-staging/v2alpha/docs/conf.py | 376 + owl-bot-staging/v2alpha/docs/index.rst | 7 + .../docs/retail_v2alpha/catalog_service.rst | 10 + .../retail_v2alpha/completion_service.rst | 6 + .../docs/retail_v2alpha/control_service.rst | 10 + .../merchant_center_account_link_service.rst | 6 + .../docs/retail_v2alpha/model_service.rst | 10 + .../retail_v2alpha/prediction_service.rst | 6 + .../docs/retail_v2alpha/product_service.rst | 10 + .../docs/retail_v2alpha/search_service.rst | 10 + .../v2alpha/docs/retail_v2alpha/services.rst | 15 + .../retail_v2alpha/serving_config_service.rst | 10 + .../v2alpha/docs/retail_v2alpha/types.rst | 6 + .../retail_v2alpha/user_event_service.rst | 6 + .../v2alpha/google/cloud/retail/__init__.py | 349 + .../google/cloud/retail/gapic_version.py | 16 + .../v2alpha/google/cloud/retail/py.typed | 2 + .../google/cloud/retail_v2alpha/__init__.py | 350 + .../cloud/retail_v2alpha/gapic_metadata.json | 1039 ++ .../cloud/retail_v2alpha/gapic_version.py | 16 + .../google/cloud/retail_v2alpha/py.typed | 2 + .../cloud/retail_v2alpha/services/__init__.py | 15 + .../services/catalog_service/__init__.py | 22 + .../services/catalog_service/async_client.py | 1613 +++ .../services/catalog_service/client.py | 1851 ++++ .../services/catalog_service/pagers.py | 140 + .../catalog_service/transports/__init__.py | 38 + .../catalog_service/transports/base.py | 325 + .../catalog_service/transports/grpc.py | 668 ++ .../transports/grpc_asyncio.py | 667 ++ .../catalog_service/transports/rest.py | 1766 ++++ .../services/completion_service/__init__.py | 22 + .../completion_service/async_client.py | 507 + .../services/completion_service/client.py | 716 ++ .../completion_service/transports/__init__.py | 38 + .../completion_service/transports/base.py | 189 + .../completion_service/transports/grpc.py | 366 + .../transports/grpc_asyncio.py | 365 + .../completion_service/transports/rest.py | 674 ++ .../services/control_service/__init__.py | 22 + .../services/control_service/async_client.py | 877 ++ .../services/control_service/client.py | 1093 ++ .../services/control_service/pagers.py | 140 + .../control_service/transports/__init__.py | 38 + .../control_service/transports/base.py | 227 + .../control_service/transports/grpc.py | 421 + .../transports/grpc_asyncio.py | 420 + .../control_service/transports/rest.py | 934 ++ .../__init__.py | 22 + .../async_client.py | 651 ++ .../client.py | 867 ++ .../transports/__init__.py | 38 + .../transports/base.py | 203 + .../transports/grpc.py | 385 + .../transports/grpc_asyncio.py | 384 + .../transports/rest.py | 768 ++ .../services/model_service/__init__.py | 22 + .../services/model_service/async_client.py | 1226 +++ .../services/model_service/client.py | 1442 +++ .../services/model_service/pagers.py | 140 + .../model_service/transports/__init__.py | 38 + .../services/model_service/transports/base.py | 275 + .../services/model_service/transports/grpc.py | 518 + .../model_service/transports/grpc_asyncio.py | 517 + .../services/model_service/transports/rest.py | 1390 +++ .../services/prediction_service/__init__.py | 22 + .../prediction_service/async_client.py | 384 + .../services/prediction_service/client.py | 592 ++ .../prediction_service/transports/__init__.py | 38 + .../prediction_service/transports/base.py | 168 + .../prediction_service/transports/grpc.py | 302 + .../transports/grpc_asyncio.py | 301 + .../prediction_service/transports/rest.py | 499 + .../services/product_service/__init__.py | 22 + .../services/product_service/async_client.py | 2060 ++++ .../services/product_service/client.py | 2271 +++++ .../services/product_service/pagers.py | 140 + .../product_service/transports/__init__.py | 38 + .../product_service/transports/base.py | 340 + .../product_service/transports/grpc.py | 810 ++ .../transports/grpc_asyncio.py | 809 ++ .../product_service/transports/rest.py | 1861 ++++ .../services/search_service/__init__.py | 22 + .../services/search_service/async_client.py | 414 + .../services/search_service/client.py | 649 ++ .../services/search_service/pagers.py | 139 + .../search_service/transports/__init__.py | 38 + .../search_service/transports/base.py | 168 + .../search_service/transports/grpc.py | 310 + .../search_service/transports/grpc_asyncio.py | 309 + .../search_service/transports/rest.py | 508 + .../serving_config_service/__init__.py | 22 + .../serving_config_service/async_client.py | 1098 ++ .../services/serving_config_service/client.py | 1314 +++ .../services/serving_config_service/pagers.py | 140 + .../transports/__init__.py | 38 + .../serving_config_service/transports/base.py | 255 + .../serving_config_service/transports/grpc.py | 480 + .../transports/grpc_asyncio.py | 479 + .../serving_config_service/transports/rest.py | 1186 +++ .../services/user_event_service/__init__.py | 22 + .../user_event_service/async_client.py | 865 ++ .../services/user_event_service/client.py | 1072 ++ .../user_event_service/transports/__init__.py | 38 + .../user_event_service/transports/base.py | 248 + .../user_event_service/transports/grpc.py | 455 + .../transports/grpc_asyncio.py | 454 + .../user_event_service/transports/rest.py | 1090 ++ .../cloud/retail_v2alpha/types/__init__.py | 348 + .../cloud/retail_v2alpha/types/catalog.py | 690 ++ .../retail_v2alpha/types/catalog_service.py | 518 + .../cloud/retail_v2alpha/types/common.py | 1262 +++ .../types/completion_service.py | 312 + .../cloud/retail_v2alpha/types/control.py | 134 + .../retail_v2alpha/types/control_service.py | 200 + .../retail_v2alpha/types/export_config.py | 214 + .../retail_v2alpha/types/import_config.py | 749 ++ .../types/merchant_center_account_link.py | 194 + .../merchant_center_account_link_service.py | 120 + .../cloud/retail_v2alpha/types/model.py | 583 ++ .../retail_v2alpha/types/model_service.py | 275 + .../types/prediction_service.py | 297 + .../cloud/retail_v2alpha/types/product.py | 800 ++ .../retail_v2alpha/types/product_service.py | 939 ++ .../cloud/retail_v2alpha/types/promotion.py | 54 + .../retail_v2alpha/types/purge_config.py | 255 + .../retail_v2alpha/types/search_service.py | 1456 +++ .../retail_v2alpha/types/serving_config.py | 359 + .../types/serving_config_service.py | 238 + .../cloud/retail_v2alpha/types/user_event.py | 526 + .../types/user_event_service.py | 203 + owl-bot-staging/v2alpha/mypy.ini | 3 + owl-bot-staging/v2alpha/noxfile.py | 184 + ...log_service_add_catalog_attribute_async.py | 56 + ...alog_service_add_catalog_attribute_sync.py | 56 + ...e_batch_remove_catalog_attributes_async.py | 53 + ...ce_batch_remove_catalog_attributes_sync.py | 53 + ...log_service_get_attributes_config_async.py | 52 + ...alog_service_get_attributes_config_sync.py | 52 + ...log_service_get_completion_config_async.py | 52 + ...alog_service_get_completion_config_sync.py | 52 + ...atalog_service_get_default_branch_async.py | 51 + ...catalog_service_get_default_branch_sync.py | 51 + ...ted_catalog_service_list_catalogs_async.py | 53 + ...ated_catalog_service_list_catalogs_sync.py | 53 + ..._service_remove_catalog_attribute_async.py | 53 + ...g_service_remove_catalog_attribute_sync.py | 53 + ...service_replace_catalog_attribute_async.py | 56 + ..._service_replace_catalog_attribute_sync.py | 56 + ...atalog_service_set_default_branch_async.py | 49 + ...catalog_service_set_default_branch_sync.py | 49 + ..._service_update_attributes_config_async.py | 55 + ...g_service_update_attributes_config_sync.py | 55 + ...ed_catalog_service_update_catalog_async.py | 56 + ...ted_catalog_service_update_catalog_sync.py | 56 + ..._service_update_completion_config_async.py | 55 + ...g_service_update_completion_config_sync.py | 55 + ...completion_service_complete_query_async.py | 53 + ..._completion_service_complete_query_sync.py | 53 + ...on_service_import_completion_data_async.py | 61 + ...ion_service_import_completion_data_sync.py | 61 + ...ed_control_service_create_control_async.py | 59 + ...ted_control_service_create_control_sync.py | 59 + ...ed_control_service_delete_control_async.py | 50 + ...ted_control_service_delete_control_sync.py | 50 + ...rated_control_service_get_control_async.py | 52 + ...erated_control_service_get_control_sync.py | 52 + ...ted_control_service_list_controls_async.py | 53 + ...ated_control_service_list_controls_sync.py | 53 + ...ed_control_service_update_control_async.py | 57 + ...ted_control_service_update_control_sync.py | 57 + ...eate_merchant_center_account_link_async.py | 61 + ...reate_merchant_center_account_link_sync.py | 61 + ...lete_merchant_center_account_link_async.py | 50 + ...elete_merchant_center_account_link_sync.py | 50 + ...ist_merchant_center_account_links_async.py | 52 + ...list_merchant_center_account_links_sync.py | 52 + ...erated_model_service_create_model_async.py | 65 + ...nerated_model_service_create_model_sync.py | 65 + ...erated_model_service_delete_model_async.py | 50 + ...nerated_model_service_delete_model_sync.py | 50 + ...generated_model_service_get_model_async.py | 52 + ..._generated_model_service_get_model_sync.py | 52 + ...nerated_model_service_list_models_async.py | 53 + ...enerated_model_service_list_models_sync.py | 53 + ...nerated_model_service_pause_model_async.py | 52 + ...enerated_model_service_pause_model_sync.py | 52 + ...erated_model_service_resume_model_async.py | 52 + ...nerated_model_service_resume_model_sync.py | 52 + ...enerated_model_service_tune_model_async.py | 56 + ...generated_model_service_tune_model_sync.py | 56 + ...erated_model_service_update_model_async.py | 60 + ...nerated_model_service_update_model_sync.py | 60 + ...erated_prediction_service_predict_async.py | 57 + ...nerated_prediction_service_predict_sync.py | 57 + ...ct_service_add_fulfillment_places_async.py | 58 + ...uct_service_add_fulfillment_places_sync.py | 58 + ...uct_service_add_local_inventories_async.py | 56 + ...duct_service_add_local_inventories_sync.py | 56 + ...ed_product_service_create_product_async.py | 57 + ...ted_product_service_create_product_sync.py | 57 + ...ed_product_service_delete_product_async.py | 50 + ...ted_product_service_delete_product_sync.py | 50 + ...rated_product_service_get_product_async.py | 52 + ...erated_product_service_get_product_sync.py | 52 + ...d_product_service_import_products_async.py | 60 + ...ed_product_service_import_products_sync.py | 60 + ...ted_product_service_list_products_async.py | 53 + ...ated_product_service_list_products_sync.py | 53 + ...ed_product_service_purge_products_async.py | 57 + ...ted_product_service_purge_products_sync.py | 57 + ...service_remove_fulfillment_places_async.py | 58 + ..._service_remove_fulfillment_places_sync.py | 58 + ..._service_remove_local_inventories_async.py | 57 + ...t_service_remove_local_inventories_sync.py | 57 + ...ted_product_service_set_inventory_async.py | 59 + ...ated_product_service_set_inventory_sync.py | 59 + ...ed_product_service_update_product_async.py | 55 + ...ted_product_service_update_product_sync.py | 55 + ...a_generated_search_service_search_async.py | 54 + ...ha_generated_search_service_search_sync.py | 54 + ...erving_config_service_add_control_async.py | 53 + ...serving_config_service_add_control_sync.py | 53 + ...fig_service_create_serving_config_async.py | 58 + ...nfig_service_create_serving_config_sync.py | 58 + ...fig_service_delete_serving_config_async.py | 50 + ...nfig_service_delete_serving_config_sync.py | 50 + ...config_service_get_serving_config_async.py | 52 + ..._config_service_get_serving_config_sync.py | 52 + ...nfig_service_list_serving_configs_async.py | 53 + ...onfig_service_list_serving_configs_sync.py | 53 + ...ing_config_service_remove_control_async.py | 53 + ...ving_config_service_remove_control_sync.py | 53 + ...fig_service_update_serving_config_async.py | 56 + ...nfig_service_update_serving_config_sync.py | 56 + ..._event_service_collect_user_event_async.py | 54 + ...r_event_service_collect_user_event_sync.py | 54 + ..._event_service_import_user_events_async.py | 61 + ...r_event_service_import_user_events_sync.py | 61 + ...r_event_service_purge_user_events_async.py | 57 + ...er_event_service_purge_user_events_sync.py | 57 + ..._event_service_rejoin_user_events_async.py | 56 + ...r_event_service_rejoin_user_events_sync.py | 56 + ...er_event_service_write_user_event_async.py | 57 + ...ser_event_service_write_user_event_sync.py | 57 + ..._metadata_google.cloud.retail.v2alpha.json | 9003 +++++++++++++++++ .../scripts/fixup_retail_v2alpha_keywords.py | 231 + owl-bot-staging/v2alpha/setup.py | 90 + .../v2alpha/testing/constraints-3.10.txt | 6 + .../v2alpha/testing/constraints-3.11.txt | 6 + .../v2alpha/testing/constraints-3.12.txt | 6 + .../v2alpha/testing/constraints-3.7.txt | 9 + .../v2alpha/testing/constraints-3.8.txt | 6 + .../v2alpha/testing/constraints-3.9.txt | 6 + owl-bot-staging/v2alpha/tests/__init__.py | 16 + .../v2alpha/tests/unit/__init__.py | 16 + .../v2alpha/tests/unit/gapic/__init__.py | 16 + .../unit/gapic/retail_v2alpha/__init__.py | 16 + .../retail_v2alpha/test_catalog_service.py | 6992 +++++++++++++ .../retail_v2alpha/test_completion_service.py | 2307 +++++ .../retail_v2alpha/test_control_service.py | 4301 ++++++++ ...st_merchant_center_account_link_service.py | 3045 ++++++ .../retail_v2alpha/test_model_service.py | 5874 +++++++++++ .../retail_v2alpha/test_prediction_service.py | 1931 ++++ .../retail_v2alpha/test_product_service.py | 7606 ++++++++++++++ .../retail_v2alpha/test_search_service.py | 2263 +++++ .../test_serving_config_service.py | 5655 +++++++++++ .../retail_v2alpha/test_user_event_service.py | 3431 +++++++ owl-bot-staging/v2beta/.coveragerc | 13 + owl-bot-staging/v2beta/.flake8 | 33 + owl-bot-staging/v2beta/MANIFEST.in | 2 + owl-bot-staging/v2beta/README.rst | 49 + .../v2beta/docs/_static/custom.css | 3 + owl-bot-staging/v2beta/docs/conf.py | 376 + owl-bot-staging/v2beta/docs/index.rst | 7 + .../docs/retail_v2beta/catalog_service.rst | 10 + .../docs/retail_v2beta/completion_service.rst | 6 + .../docs/retail_v2beta/control_service.rst | 10 + .../docs/retail_v2beta/model_service.rst | 10 + .../docs/retail_v2beta/prediction_service.rst | 6 + .../docs/retail_v2beta/product_service.rst | 10 + .../docs/retail_v2beta/search_service.rst | 10 + .../v2beta/docs/retail_v2beta/services.rst | 14 + .../retail_v2beta/serving_config_service.rst | 10 + .../v2beta/docs/retail_v2beta/types.rst | 6 + .../docs/retail_v2beta/user_event_service.rst | 6 + .../v2beta/google/cloud/retail/__init__.py | 325 + .../google/cloud/retail/gapic_version.py | 16 + .../v2beta/google/cloud/retail/py.typed | 2 + .../google/cloud/retail_v2beta/__init__.py | 326 + .../cloud/retail_v2beta/gapic_metadata.json | 960 ++ .../cloud/retail_v2beta/gapic_version.py | 16 + .../google/cloud/retail_v2beta/py.typed | 2 + .../cloud/retail_v2beta/services/__init__.py | 15 + .../services/catalog_service/__init__.py | 22 + .../services/catalog_service/async_client.py | 1611 +++ .../services/catalog_service/client.py | 1849 ++++ .../services/catalog_service/pagers.py | 140 + .../catalog_service/transports/__init__.py | 38 + .../catalog_service/transports/base.py | 325 + .../catalog_service/transports/grpc.py | 668 ++ .../transports/grpc_asyncio.py | 667 ++ .../catalog_service/transports/rest.py | 1762 ++++ .../services/completion_service/__init__.py | 22 + .../completion_service/async_client.py | 507 + .../services/completion_service/client.py | 716 ++ .../completion_service/transports/__init__.py | 38 + .../completion_service/transports/base.py | 189 + .../completion_service/transports/grpc.py | 366 + .../transports/grpc_asyncio.py | 365 + .../completion_service/transports/rest.py | 666 ++ .../services/control_service/__init__.py | 22 + .../services/control_service/async_client.py | 877 ++ .../services/control_service/client.py | 1093 ++ .../services/control_service/pagers.py | 140 + .../control_service/transports/__init__.py | 38 + .../control_service/transports/base.py | 227 + .../control_service/transports/grpc.py | 421 + .../transports/grpc_asyncio.py | 420 + .../control_service/transports/rest.py | 930 ++ .../services/model_service/__init__.py | 22 + .../services/model_service/async_client.py | 1220 +++ .../services/model_service/client.py | 1436 +++ .../services/model_service/pagers.py | 140 + .../model_service/transports/__init__.py | 38 + .../services/model_service/transports/base.py | 275 + .../services/model_service/transports/grpc.py | 518 + .../model_service/transports/grpc_asyncio.py | 517 + .../services/model_service/transports/rest.py | 1382 +++ .../services/prediction_service/__init__.py | 22 + .../prediction_service/async_client.py | 384 + .../services/prediction_service/client.py | 592 ++ .../prediction_service/transports/__init__.py | 38 + .../prediction_service/transports/base.py | 168 + .../prediction_service/transports/grpc.py | 302 + .../transports/grpc_asyncio.py | 301 + .../prediction_service/transports/rest.py | 495 + .../services/product_service/__init__.py | 22 + .../services/product_service/async_client.py | 1941 ++++ .../services/product_service/client.py | 2151 ++++ .../services/product_service/pagers.py | 140 + .../product_service/transports/__init__.py | 38 + .../product_service/transports/base.py | 325 + .../product_service/transports/grpc.py | 764 ++ .../transports/grpc_asyncio.py | 763 ++ .../product_service/transports/rest.py | 1731 ++++ .../services/search_service/__init__.py | 22 + .../services/search_service/async_client.py | 414 + .../services/search_service/client.py | 649 ++ .../services/search_service/pagers.py | 139 + .../search_service/transports/__init__.py | 38 + .../search_service/transports/base.py | 168 + .../search_service/transports/grpc.py | 310 + .../search_service/transports/grpc_asyncio.py | 309 + .../search_service/transports/rest.py | 504 + .../serving_config_service/__init__.py | 22 + .../serving_config_service/async_client.py | 1098 ++ .../services/serving_config_service/client.py | 1314 +++ .../services/serving_config_service/pagers.py | 140 + .../transports/__init__.py | 38 + .../serving_config_service/transports/base.py | 255 + .../serving_config_service/transports/grpc.py | 480 + .../transports/grpc_asyncio.py | 479 + .../serving_config_service/transports/rest.py | 1182 +++ .../services/user_event_service/__init__.py | 22 + .../user_event_service/async_client.py | 865 ++ .../services/user_event_service/client.py | 1072 ++ .../user_event_service/transports/__init__.py | 38 + .../user_event_service/transports/base.py | 248 + .../user_event_service/transports/grpc.py | 455 + .../transports/grpc_asyncio.py | 454 + .../user_event_service/transports/rest.py | 1082 ++ .../cloud/retail_v2beta/types/__init__.py | 324 + .../cloud/retail_v2beta/types/catalog.py | 689 ++ .../retail_v2beta/types/catalog_service.py | 518 + .../cloud/retail_v2beta/types/common.py | 1259 +++ .../retail_v2beta/types/completion_service.py | 251 + .../cloud/retail_v2beta/types/control.py | 134 + .../retail_v2beta/types/control_service.py | 200 + .../retail_v2beta/types/export_config.py | 214 + .../retail_v2beta/types/import_config.py | 704 ++ .../google/cloud/retail_v2beta/types/model.py | 320 + .../retail_v2beta/types/model_service.py | 274 + .../retail_v2beta/types/prediction_service.py | 297 + .../cloud/retail_v2beta/types/product.py | 800 ++ .../retail_v2beta/types/product_service.py | 892 ++ .../cloud/retail_v2beta/types/promotion.py | 54 + .../cloud/retail_v2beta/types/purge_config.py | 111 + .../retail_v2beta/types/search_service.py | 1417 +++ .../retail_v2beta/types/serving_config.py | 359 + .../types/serving_config_service.py | 238 + .../cloud/retail_v2beta/types/user_event.py | 526 + .../retail_v2beta/types/user_event_service.py | 203 + owl-bot-staging/v2beta/mypy.ini | 3 + owl-bot-staging/v2beta/noxfile.py | 184 + ...log_service_add_catalog_attribute_async.py | 56 + ...alog_service_add_catalog_attribute_sync.py | 56 + ...e_batch_remove_catalog_attributes_async.py | 53 + ...ce_batch_remove_catalog_attributes_sync.py | 53 + ...log_service_get_attributes_config_async.py | 52 + ...alog_service_get_attributes_config_sync.py | 52 + ...log_service_get_completion_config_async.py | 52 + ...alog_service_get_completion_config_sync.py | 52 + ...atalog_service_get_default_branch_async.py | 51 + ...catalog_service_get_default_branch_sync.py | 51 + ...ted_catalog_service_list_catalogs_async.py | 53 + ...ated_catalog_service_list_catalogs_sync.py | 53 + ..._service_remove_catalog_attribute_async.py | 53 + ...g_service_remove_catalog_attribute_sync.py | 53 + ...service_replace_catalog_attribute_async.py | 56 + ..._service_replace_catalog_attribute_sync.py | 56 + ...atalog_service_set_default_branch_async.py | 49 + ...catalog_service_set_default_branch_sync.py | 49 + ..._service_update_attributes_config_async.py | 55 + ...g_service_update_attributes_config_sync.py | 55 + ...ed_catalog_service_update_catalog_async.py | 56 + ...ted_catalog_service_update_catalog_sync.py | 56 + ..._service_update_completion_config_async.py | 55 + ...g_service_update_completion_config_sync.py | 55 + ...completion_service_complete_query_async.py | 53 + ..._completion_service_complete_query_sync.py | 53 + ...on_service_import_completion_data_async.py | 61 + ...ion_service_import_completion_data_sync.py | 61 + ...ed_control_service_create_control_async.py | 59 + ...ted_control_service_create_control_sync.py | 59 + ...ed_control_service_delete_control_async.py | 50 + ...ted_control_service_delete_control_sync.py | 50 + ...rated_control_service_get_control_async.py | 52 + ...erated_control_service_get_control_sync.py | 52 + ...ted_control_service_list_controls_async.py | 53 + ...ated_control_service_list_controls_sync.py | 53 + ...ed_control_service_update_control_async.py | 57 + ...ted_control_service_update_control_sync.py | 57 + ...erated_model_service_create_model_async.py | 62 + ...nerated_model_service_create_model_sync.py | 62 + ...erated_model_service_delete_model_async.py | 50 + ...nerated_model_service_delete_model_sync.py | 50 + ...generated_model_service_get_model_async.py | 52 + ..._generated_model_service_get_model_sync.py | 52 + ...nerated_model_service_list_models_async.py | 53 + ...enerated_model_service_list_models_sync.py | 53 + ...nerated_model_service_pause_model_async.py | 52 + ...enerated_model_service_pause_model_sync.py | 52 + ...erated_model_service_resume_model_async.py | 52 + ...nerated_model_service_resume_model_sync.py | 52 + ...enerated_model_service_tune_model_async.py | 56 + ...generated_model_service_tune_model_sync.py | 56 + ...erated_model_service_update_model_async.py | 57 + ...nerated_model_service_update_model_sync.py | 57 + ...erated_prediction_service_predict_async.py | 57 + ...nerated_prediction_service_predict_sync.py | 57 + ...ct_service_add_fulfillment_places_async.py | 58 + ...uct_service_add_fulfillment_places_sync.py | 58 + ...uct_service_add_local_inventories_async.py | 56 + ...duct_service_add_local_inventories_sync.py | 56 + ...ed_product_service_create_product_async.py | 57 + ...ted_product_service_create_product_sync.py | 57 + ...ed_product_service_delete_product_async.py | 50 + ...ted_product_service_delete_product_sync.py | 50 + ...rated_product_service_get_product_async.py | 52 + ...erated_product_service_get_product_sync.py | 52 + ...d_product_service_import_products_async.py | 60 + ...ed_product_service_import_products_sync.py | 60 + ...ted_product_service_list_products_async.py | 53 + ...ated_product_service_list_products_sync.py | 53 + ...service_remove_fulfillment_places_async.py | 58 + ..._service_remove_fulfillment_places_sync.py | 58 + ..._service_remove_local_inventories_async.py | 57 + ...t_service_remove_local_inventories_sync.py | 57 + ...ted_product_service_set_inventory_async.py | 59 + ...ated_product_service_set_inventory_sync.py | 59 + ...ed_product_service_update_product_async.py | 55 + ...ted_product_service_update_product_sync.py | 55 + ...a_generated_search_service_search_async.py | 54 + ...ta_generated_search_service_search_sync.py | 54 + ...erving_config_service_add_control_async.py | 53 + ...serving_config_service_add_control_sync.py | 53 + ...fig_service_create_serving_config_async.py | 58 + ...nfig_service_create_serving_config_sync.py | 58 + ...fig_service_delete_serving_config_async.py | 50 + ...nfig_service_delete_serving_config_sync.py | 50 + ...config_service_get_serving_config_async.py | 52 + ..._config_service_get_serving_config_sync.py | 52 + ...nfig_service_list_serving_configs_async.py | 53 + ...onfig_service_list_serving_configs_sync.py | 53 + ...ing_config_service_remove_control_async.py | 53 + ...ving_config_service_remove_control_sync.py | 53 + ...fig_service_update_serving_config_async.py | 56 + ...nfig_service_update_serving_config_sync.py | 56 + ..._event_service_collect_user_event_async.py | 54 + ...r_event_service_collect_user_event_sync.py | 54 + ..._event_service_import_user_events_async.py | 61 + ...r_event_service_import_user_events_sync.py | 61 + ...r_event_service_purge_user_events_async.py | 57 + ...er_event_service_purge_user_events_sync.py | 57 + ..._event_service_rejoin_user_events_async.py | 56 + ...r_event_service_rejoin_user_events_sync.py | 56 + ...er_event_service_write_user_event_async.py | 57 + ...ser_event_service_write_user_event_sync.py | 57 + ...t_metadata_google.cloud.retail.v2beta.json | 8365 +++++++++++++++ .../scripts/fixup_retail_v2beta_keywords.py | 227 + owl-bot-staging/v2beta/setup.py | 90 + .../v2beta/testing/constraints-3.10.txt | 6 + .../v2beta/testing/constraints-3.11.txt | 6 + .../v2beta/testing/constraints-3.12.txt | 6 + .../v2beta/testing/constraints-3.7.txt | 9 + .../v2beta/testing/constraints-3.8.txt | 6 + .../v2beta/testing/constraints-3.9.txt | 6 + owl-bot-staging/v2beta/tests/__init__.py | 16 + owl-bot-staging/v2beta/tests/unit/__init__.py | 16 + .../v2beta/tests/unit/gapic/__init__.py | 16 + .../unit/gapic/retail_v2beta/__init__.py | 16 + .../retail_v2beta/test_catalog_service.py | 6992 +++++++++++++ .../retail_v2beta/test_completion_service.py | 2307 +++++ .../retail_v2beta/test_control_service.py | 4301 ++++++++ .../gapic/retail_v2beta/test_model_service.py | 5874 +++++++++++ .../retail_v2beta/test_prediction_service.py | 1931 ++++ .../retail_v2beta/test_product_service.py | 7266 +++++++++++++ .../retail_v2beta/test_search_service.py | 2263 +++++ .../test_serving_config_service.py | 5655 +++++++++++ .../retail_v2beta/test_user_event_service.py | 3431 +++++++ 776 files changed, 332897 insertions(+) create mode 100644 owl-bot-staging/v2/.coveragerc create mode 100644 owl-bot-staging/v2/.flake8 create mode 100644 owl-bot-staging/v2/MANIFEST.in create mode 100644 owl-bot-staging/v2/README.rst create mode 100644 owl-bot-staging/v2/docs/_static/custom.css create mode 100644 owl-bot-staging/v2/docs/conf.py create mode 100644 owl-bot-staging/v2/docs/index.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/catalog_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/completion_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/control_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/model_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/prediction_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/product_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/search_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/services.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/serving_config_service.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/types.rst create mode 100644 owl-bot-staging/v2/docs/retail_v2/user_event_service.rst create mode 100644 owl-bot-staging/v2/google/cloud/retail/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail/gapic_version.py create mode 100644 owl-bot-staging/v2/google/cloud/retail/py.typed create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/gapic_version.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/py.typed create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/pagers.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/rest.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/common.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/control.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/control_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/model.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/model_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/product.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/promotion.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config_service.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py create mode 100644 owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py create mode 100644 owl-bot-staging/v2/mypy.ini create mode 100644 owl-bot-staging/v2/noxfile.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_delete_product_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_delete_product_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_get_product_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_get_product_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_list_products_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_list_products_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_async.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_sync.py create mode 100644 owl-bot-staging/v2/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json create mode 100644 owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py create mode 100644 owl-bot-staging/v2/setup.py create mode 100644 owl-bot-staging/v2/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v2/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v2/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v2/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v2/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v2/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v2/tests/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_control_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_model_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_serving_config_service.py create mode 100644 owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py create mode 100644 owl-bot-staging/v2alpha/.coveragerc create mode 100644 owl-bot-staging/v2alpha/.flake8 create mode 100644 owl-bot-staging/v2alpha/MANIFEST.in create mode 100644 owl-bot-staging/v2alpha/README.rst create mode 100644 owl-bot-staging/v2alpha/docs/_static/custom.css create mode 100644 owl-bot-staging/v2alpha/docs/conf.py create mode 100644 owl-bot-staging/v2alpha/docs/index.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/catalog_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/completion_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/control_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/merchant_center_account_link_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/model_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/prediction_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/product_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/search_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/services.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/serving_config_service.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/types.rst create mode 100644 owl-bot-staging/v2alpha/docs/retail_v2alpha/user_event_service.rst create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail/gapic_version.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail/py.typed create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/gapic_metadata.json create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/gapic_version.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/py.typed create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/pagers.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/pagers.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/pagers.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/pagers.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/pagers.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/pagers.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/async_client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/client.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/base.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/rest.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/__init__.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/common.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/completion_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/export_config.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/import_config.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/prediction_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/promotion.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/purge_config.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/search_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config_service.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event.py create mode 100644 owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event_service.py create mode 100644 owl-bot-staging/v2alpha/mypy.ini create mode 100644 owl-bot-staging/v2alpha/noxfile.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_delete_product_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_delete_product_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_get_product_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_get_product_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_list_products_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_list_products_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_async.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_sync.py create mode 100644 owl-bot-staging/v2alpha/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json create mode 100644 owl-bot-staging/v2alpha/scripts/fixup_retail_v2alpha_keywords.py create mode 100644 owl-bot-staging/v2alpha/setup.py create mode 100644 owl-bot-staging/v2alpha/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v2alpha/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v2alpha/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v2alpha/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v2alpha/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v2alpha/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v2alpha/tests/__init__.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/__init__.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/__init__.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_catalog_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_completion_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_control_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_merchant_center_account_link_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_model_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_prediction_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_product_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_search_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_serving_config_service.py create mode 100644 owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_user_event_service.py create mode 100644 owl-bot-staging/v2beta/.coveragerc create mode 100644 owl-bot-staging/v2beta/.flake8 create mode 100644 owl-bot-staging/v2beta/MANIFEST.in create mode 100644 owl-bot-staging/v2beta/README.rst create mode 100644 owl-bot-staging/v2beta/docs/_static/custom.css create mode 100644 owl-bot-staging/v2beta/docs/conf.py create mode 100644 owl-bot-staging/v2beta/docs/index.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/catalog_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/completion_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/control_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/model_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/prediction_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/product_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/search_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/services.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/serving_config_service.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/types.rst create mode 100644 owl-bot-staging/v2beta/docs/retail_v2beta/user_event_service.rst create mode 100644 owl-bot-staging/v2beta/google/cloud/retail/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail/gapic_version.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail/py.typed create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/gapic_metadata.json create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/gapic_version.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/py.typed create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/pagers.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/pagers.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/pagers.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/pagers.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/pagers.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/pagers.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/async_client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/client.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/base.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/rest.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/__init__.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/common.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/completion_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/export_config.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/import_config.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/prediction_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/promotion.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/purge_config.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/search_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config_service.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event.py create mode 100644 owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event_service.py create mode 100644 owl-bot-staging/v2beta/mypy.ini create mode 100644 owl-bot-staging/v2beta/noxfile.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_delete_product_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_delete_product_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_get_product_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_get_product_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_list_products_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_list_products_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_async.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_sync.py create mode 100644 owl-bot-staging/v2beta/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json create mode 100644 owl-bot-staging/v2beta/scripts/fixup_retail_v2beta_keywords.py create mode 100644 owl-bot-staging/v2beta/setup.py create mode 100644 owl-bot-staging/v2beta/testing/constraints-3.10.txt create mode 100644 owl-bot-staging/v2beta/testing/constraints-3.11.txt create mode 100644 owl-bot-staging/v2beta/testing/constraints-3.12.txt create mode 100644 owl-bot-staging/v2beta/testing/constraints-3.7.txt create mode 100644 owl-bot-staging/v2beta/testing/constraints-3.8.txt create mode 100644 owl-bot-staging/v2beta/testing/constraints-3.9.txt create mode 100644 owl-bot-staging/v2beta/tests/__init__.py create mode 100644 owl-bot-staging/v2beta/tests/unit/__init__.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/__init__.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/__init__.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_catalog_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_completion_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_control_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_model_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_prediction_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_product_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_search_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_serving_config_service.py create mode 100644 owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_user_event_service.py diff --git a/owl-bot-staging/v2/.coveragerc b/owl-bot-staging/v2/.coveragerc new file mode 100644 index 00000000..3d15c56d --- /dev/null +++ b/owl-bot-staging/v2/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/retail/__init__.py + google/cloud/retail/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/v2/.flake8 b/owl-bot-staging/v2/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v2/.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/v2/MANIFEST.in b/owl-bot-staging/v2/MANIFEST.in new file mode 100644 index 00000000..985b915c --- /dev/null +++ b/owl-bot-staging/v2/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/retail *.py +recursive-include google/cloud/retail_v2 *.py diff --git a/owl-bot-staging/v2/README.rst b/owl-bot-staging/v2/README.rst new file mode 100644 index 00000000..cb039760 --- /dev/null +++ b/owl-bot-staging/v2/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Retail 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 Retail 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/v2/docs/_static/custom.css b/owl-bot-staging/v2/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v2/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v2/docs/conf.py b/owl-bot-staging/v2/docs/conf.py new file mode 100644 index 00000000..995e6a64 --- /dev/null +++ b/owl-bot-staging/v2/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-retail 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-retail" +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-retail-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-retail.tex", + u"google-cloud-retail 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-retail", + u"Google Cloud Retail 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-retail", + u"google-cloud-retail Documentation", + author, + "google-cloud-retail", + "GAPIC library for Google Cloud Retail 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/v2/docs/index.rst b/owl-bot-staging/v2/docs/index.rst new file mode 100644 index 00000000..c70f61bc --- /dev/null +++ b/owl-bot-staging/v2/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + retail_v2/services + retail_v2/types diff --git a/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst b/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst new file mode 100644 index 00000000..5b7227d9 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/catalog_service.rst @@ -0,0 +1,10 @@ +CatalogService +-------------------------------- + +.. automodule:: google.cloud.retail_v2.services.catalog_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.catalog_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/completion_service.rst b/owl-bot-staging/v2/docs/retail_v2/completion_service.rst new file mode 100644 index 00000000..551f89ed --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/completion_service.rst @@ -0,0 +1,6 @@ +CompletionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2.services.completion_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/control_service.rst b/owl-bot-staging/v2/docs/retail_v2/control_service.rst new file mode 100644 index 00000000..f53695e5 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/control_service.rst @@ -0,0 +1,10 @@ +ControlService +-------------------------------- + +.. automodule:: google.cloud.retail_v2.services.control_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.control_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/model_service.rst b/owl-bot-staging/v2/docs/retail_v2/model_service.rst new file mode 100644 index 00000000..68191fad --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/model_service.rst @@ -0,0 +1,10 @@ +ModelService +------------------------------ + +.. automodule:: google.cloud.retail_v2.services.model_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.model_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst b/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst new file mode 100644 index 00000000..12ffb6ee --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/prediction_service.rst @@ -0,0 +1,6 @@ +PredictionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2.services.prediction_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/product_service.rst b/owl-bot-staging/v2/docs/retail_v2/product_service.rst new file mode 100644 index 00000000..0b8fa911 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/product_service.rst @@ -0,0 +1,10 @@ +ProductService +-------------------------------- + +.. automodule:: google.cloud.retail_v2.services.product_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.product_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/search_service.rst b/owl-bot-staging/v2/docs/retail_v2/search_service.rst new file mode 100644 index 00000000..af72819d --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/search_service.rst @@ -0,0 +1,10 @@ +SearchService +------------------------------- + +.. automodule:: google.cloud.retail_v2.services.search_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.search_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/services.rst b/owl-bot-staging/v2/docs/retail_v2/services.rst new file mode 100644 index 00000000..eba07fc3 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/services.rst @@ -0,0 +1,14 @@ +Services for Google Cloud Retail v2 API +======================================= +.. toctree:: + :maxdepth: 2 + + catalog_service + completion_service + control_service + model_service + prediction_service + product_service + search_service + serving_config_service + user_event_service diff --git a/owl-bot-staging/v2/docs/retail_v2/serving_config_service.rst b/owl-bot-staging/v2/docs/retail_v2/serving_config_service.rst new file mode 100644 index 00000000..22dab4ca --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/serving_config_service.rst @@ -0,0 +1,10 @@ +ServingConfigService +-------------------------------------- + +.. automodule:: google.cloud.retail_v2.services.serving_config_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2.services.serving_config_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/docs/retail_v2/types.rst b/owl-bot-staging/v2/docs/retail_v2/types.rst new file mode 100644 index 00000000..24ccf5a1 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Retail v2 API +==================================== + +.. automodule:: google.cloud.retail_v2.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst b/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst new file mode 100644 index 00000000..00e214a9 --- /dev/null +++ b/owl-bot-staging/v2/docs/retail_v2/user_event_service.rst @@ -0,0 +1,6 @@ +UserEventService +---------------------------------- + +.. automodule:: google.cloud.retail_v2.services.user_event_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2/google/cloud/retail/__init__.py b/owl-bot-staging/v2/google/cloud/retail/__init__.py new file mode 100644 index 00000000..03c51757 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail/__init__.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.retail_v2.services.catalog_service.client import CatalogServiceClient +from google.cloud.retail_v2.services.catalog_service.async_client import CatalogServiceAsyncClient +from google.cloud.retail_v2.services.completion_service.client import CompletionServiceClient +from google.cloud.retail_v2.services.completion_service.async_client import CompletionServiceAsyncClient +from google.cloud.retail_v2.services.control_service.client import ControlServiceClient +from google.cloud.retail_v2.services.control_service.async_client import ControlServiceAsyncClient +from google.cloud.retail_v2.services.model_service.client import ModelServiceClient +from google.cloud.retail_v2.services.model_service.async_client import ModelServiceAsyncClient +from google.cloud.retail_v2.services.prediction_service.client import PredictionServiceClient +from google.cloud.retail_v2.services.prediction_service.async_client import PredictionServiceAsyncClient +from google.cloud.retail_v2.services.product_service.client import ProductServiceClient +from google.cloud.retail_v2.services.product_service.async_client import ProductServiceAsyncClient +from google.cloud.retail_v2.services.search_service.client import SearchServiceClient +from google.cloud.retail_v2.services.search_service.async_client import SearchServiceAsyncClient +from google.cloud.retail_v2.services.serving_config_service.client import ServingConfigServiceClient +from google.cloud.retail_v2.services.serving_config_service.async_client import ServingConfigServiceAsyncClient +from google.cloud.retail_v2.services.user_event_service.client import UserEventServiceClient +from google.cloud.retail_v2.services.user_event_service.async_client import UserEventServiceAsyncClient + +from google.cloud.retail_v2.types.catalog import AttributesConfig +from google.cloud.retail_v2.types.catalog import Catalog +from google.cloud.retail_v2.types.catalog import CatalogAttribute +from google.cloud.retail_v2.types.catalog import CompletionConfig +from google.cloud.retail_v2.types.catalog import ProductLevelConfig +from google.cloud.retail_v2.types.catalog_service import AddCatalogAttributeRequest +from google.cloud.retail_v2.types.catalog_service import GetAttributesConfigRequest +from google.cloud.retail_v2.types.catalog_service import GetCompletionConfigRequest +from google.cloud.retail_v2.types.catalog_service import GetDefaultBranchRequest +from google.cloud.retail_v2.types.catalog_service import GetDefaultBranchResponse +from google.cloud.retail_v2.types.catalog_service import ListCatalogsRequest +from google.cloud.retail_v2.types.catalog_service import ListCatalogsResponse +from google.cloud.retail_v2.types.catalog_service import RemoveCatalogAttributeRequest +from google.cloud.retail_v2.types.catalog_service import ReplaceCatalogAttributeRequest +from google.cloud.retail_v2.types.catalog_service import SetDefaultBranchRequest +from google.cloud.retail_v2.types.catalog_service import UpdateAttributesConfigRequest +from google.cloud.retail_v2.types.catalog_service import UpdateCatalogRequest +from google.cloud.retail_v2.types.catalog_service import UpdateCompletionConfigRequest +from google.cloud.retail_v2.types.common import Audience +from google.cloud.retail_v2.types.common import ColorInfo +from google.cloud.retail_v2.types.common import Condition +from google.cloud.retail_v2.types.common import CustomAttribute +from google.cloud.retail_v2.types.common import FulfillmentInfo +from google.cloud.retail_v2.types.common import Image +from google.cloud.retail_v2.types.common import Interval +from google.cloud.retail_v2.types.common import LocalInventory +from google.cloud.retail_v2.types.common import PriceInfo +from google.cloud.retail_v2.types.common import Rating +from google.cloud.retail_v2.types.common import Rule +from google.cloud.retail_v2.types.common import UserInfo +from google.cloud.retail_v2.types.common import AttributeConfigLevel +from google.cloud.retail_v2.types.common import RecommendationsFilteringOption +from google.cloud.retail_v2.types.common import SearchSolutionUseCase +from google.cloud.retail_v2.types.common import SolutionType +from google.cloud.retail_v2.types.completion_service import CompleteQueryRequest +from google.cloud.retail_v2.types.completion_service import CompleteQueryResponse +from google.cloud.retail_v2.types.control import Control +from google.cloud.retail_v2.types.control_service import CreateControlRequest +from google.cloud.retail_v2.types.control_service import DeleteControlRequest +from google.cloud.retail_v2.types.control_service import GetControlRequest +from google.cloud.retail_v2.types.control_service import ListControlsRequest +from google.cloud.retail_v2.types.control_service import ListControlsResponse +from google.cloud.retail_v2.types.control_service import UpdateControlRequest +from google.cloud.retail_v2.types.import_config import BigQuerySource +from google.cloud.retail_v2.types.import_config import CompletionDataInputConfig +from google.cloud.retail_v2.types.import_config import GcsSource +from google.cloud.retail_v2.types.import_config import ImportCompletionDataRequest +from google.cloud.retail_v2.types.import_config import ImportCompletionDataResponse +from google.cloud.retail_v2.types.import_config import ImportErrorsConfig +from google.cloud.retail_v2.types.import_config import ImportMetadata +from google.cloud.retail_v2.types.import_config import ImportProductsRequest +from google.cloud.retail_v2.types.import_config import ImportProductsResponse +from google.cloud.retail_v2.types.import_config import ImportUserEventsRequest +from google.cloud.retail_v2.types.import_config import ImportUserEventsResponse +from google.cloud.retail_v2.types.import_config import ProductInlineSource +from google.cloud.retail_v2.types.import_config import ProductInputConfig +from google.cloud.retail_v2.types.import_config import UserEventImportSummary +from google.cloud.retail_v2.types.import_config import UserEventInlineSource +from google.cloud.retail_v2.types.import_config import UserEventInputConfig +from google.cloud.retail_v2.types.model import Model +from google.cloud.retail_v2.types.model_service import CreateModelMetadata +from google.cloud.retail_v2.types.model_service import CreateModelRequest +from google.cloud.retail_v2.types.model_service import DeleteModelRequest +from google.cloud.retail_v2.types.model_service import GetModelRequest +from google.cloud.retail_v2.types.model_service import ListModelsRequest +from google.cloud.retail_v2.types.model_service import ListModelsResponse +from google.cloud.retail_v2.types.model_service import PauseModelRequest +from google.cloud.retail_v2.types.model_service import ResumeModelRequest +from google.cloud.retail_v2.types.model_service import TuneModelMetadata +from google.cloud.retail_v2.types.model_service import TuneModelRequest +from google.cloud.retail_v2.types.model_service import TuneModelResponse +from google.cloud.retail_v2.types.model_service import UpdateModelRequest +from google.cloud.retail_v2.types.prediction_service import PredictRequest +from google.cloud.retail_v2.types.prediction_service import PredictResponse +from google.cloud.retail_v2.types.product import Product +from google.cloud.retail_v2.types.product_service import AddFulfillmentPlacesMetadata +from google.cloud.retail_v2.types.product_service import AddFulfillmentPlacesRequest +from google.cloud.retail_v2.types.product_service import AddFulfillmentPlacesResponse +from google.cloud.retail_v2.types.product_service import AddLocalInventoriesMetadata +from google.cloud.retail_v2.types.product_service import AddLocalInventoriesRequest +from google.cloud.retail_v2.types.product_service import AddLocalInventoriesResponse +from google.cloud.retail_v2.types.product_service import CreateProductRequest +from google.cloud.retail_v2.types.product_service import DeleteProductRequest +from google.cloud.retail_v2.types.product_service import GetProductRequest +from google.cloud.retail_v2.types.product_service import ListProductsRequest +from google.cloud.retail_v2.types.product_service import ListProductsResponse +from google.cloud.retail_v2.types.product_service import RemoveFulfillmentPlacesMetadata +from google.cloud.retail_v2.types.product_service import RemoveFulfillmentPlacesRequest +from google.cloud.retail_v2.types.product_service import RemoveFulfillmentPlacesResponse +from google.cloud.retail_v2.types.product_service import RemoveLocalInventoriesMetadata +from google.cloud.retail_v2.types.product_service import RemoveLocalInventoriesRequest +from google.cloud.retail_v2.types.product_service import RemoveLocalInventoriesResponse +from google.cloud.retail_v2.types.product_service import SetInventoryMetadata +from google.cloud.retail_v2.types.product_service import SetInventoryRequest +from google.cloud.retail_v2.types.product_service import SetInventoryResponse +from google.cloud.retail_v2.types.product_service import UpdateProductRequest +from google.cloud.retail_v2.types.promotion import Promotion +from google.cloud.retail_v2.types.purge_config import PurgeMetadata +from google.cloud.retail_v2.types.purge_config import PurgeUserEventsRequest +from google.cloud.retail_v2.types.purge_config import PurgeUserEventsResponse +from google.cloud.retail_v2.types.search_service import ExperimentInfo +from google.cloud.retail_v2.types.search_service import SearchRequest +from google.cloud.retail_v2.types.search_service import SearchResponse +from google.cloud.retail_v2.types.serving_config import ServingConfig +from google.cloud.retail_v2.types.serving_config_service import AddControlRequest +from google.cloud.retail_v2.types.serving_config_service import CreateServingConfigRequest +from google.cloud.retail_v2.types.serving_config_service import DeleteServingConfigRequest +from google.cloud.retail_v2.types.serving_config_service import GetServingConfigRequest +from google.cloud.retail_v2.types.serving_config_service import ListServingConfigsRequest +from google.cloud.retail_v2.types.serving_config_service import ListServingConfigsResponse +from google.cloud.retail_v2.types.serving_config_service import RemoveControlRequest +from google.cloud.retail_v2.types.serving_config_service import UpdateServingConfigRequest +from google.cloud.retail_v2.types.user_event import CompletionDetail +from google.cloud.retail_v2.types.user_event import ProductDetail +from google.cloud.retail_v2.types.user_event import PurchaseTransaction +from google.cloud.retail_v2.types.user_event import UserEvent +from google.cloud.retail_v2.types.user_event_service import CollectUserEventRequest +from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsMetadata +from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsRequest +from google.cloud.retail_v2.types.user_event_service import RejoinUserEventsResponse +from google.cloud.retail_v2.types.user_event_service import WriteUserEventRequest + +__all__ = ('CatalogServiceClient', + 'CatalogServiceAsyncClient', + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', + 'ControlServiceClient', + 'ControlServiceAsyncClient', + 'ModelServiceClient', + 'ModelServiceAsyncClient', + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', + 'ProductServiceClient', + 'ProductServiceAsyncClient', + 'SearchServiceClient', + 'SearchServiceAsyncClient', + 'ServingConfigServiceClient', + 'ServingConfigServiceAsyncClient', + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', + 'AttributesConfig', + 'Catalog', + 'CatalogAttribute', + 'CompletionConfig', + 'ProductLevelConfig', + 'AddCatalogAttributeRequest', + 'GetAttributesConfigRequest', + 'GetCompletionConfigRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'RemoveCatalogAttributeRequest', + 'ReplaceCatalogAttributeRequest', + 'SetDefaultBranchRequest', + 'UpdateAttributesConfigRequest', + 'UpdateCatalogRequest', + 'UpdateCompletionConfigRequest', + 'Audience', + 'ColorInfo', + 'Condition', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'LocalInventory', + 'PriceInfo', + 'Rating', + 'Rule', + 'UserInfo', + 'AttributeConfigLevel', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'SolutionType', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'Control', + 'CreateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + 'UpdateControlRequest', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'Model', + 'CreateModelMetadata', + 'CreateModelRequest', + 'DeleteModelRequest', + 'GetModelRequest', + 'ListModelsRequest', + 'ListModelsResponse', + 'PauseModelRequest', + 'ResumeModelRequest', + 'TuneModelMetadata', + 'TuneModelRequest', + 'TuneModelResponse', + 'UpdateModelRequest', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'Promotion', + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'ExperimentInfo', + 'SearchRequest', + 'SearchResponse', + 'ServingConfig', + 'AddControlRequest', + 'CreateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'RemoveControlRequest', + 'UpdateServingConfigRequest', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2/google/cloud/retail/gapic_version.py b/owl-bot-staging/v2/google/cloud/retail/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail/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/v2/google/cloud/retail/py.typed b/owl-bot-staging/v2/google/cloud/retail/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py new file mode 100644 index 00000000..80f1b2c1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/__init__.py @@ -0,0 +1,302 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.catalog_service import CatalogServiceClient +from .services.catalog_service import CatalogServiceAsyncClient +from .services.completion_service import CompletionServiceClient +from .services.completion_service import CompletionServiceAsyncClient +from .services.control_service import ControlServiceClient +from .services.control_service import ControlServiceAsyncClient +from .services.model_service import ModelServiceClient +from .services.model_service import ModelServiceAsyncClient +from .services.prediction_service import PredictionServiceClient +from .services.prediction_service import PredictionServiceAsyncClient +from .services.product_service import ProductServiceClient +from .services.product_service import ProductServiceAsyncClient +from .services.search_service import SearchServiceClient +from .services.search_service import SearchServiceAsyncClient +from .services.serving_config_service import ServingConfigServiceClient +from .services.serving_config_service import ServingConfigServiceAsyncClient +from .services.user_event_service import UserEventServiceClient +from .services.user_event_service import UserEventServiceAsyncClient + +from .types.catalog import AttributesConfig +from .types.catalog import Catalog +from .types.catalog import CatalogAttribute +from .types.catalog import CompletionConfig +from .types.catalog import ProductLevelConfig +from .types.catalog_service import AddCatalogAttributeRequest +from .types.catalog_service import GetAttributesConfigRequest +from .types.catalog_service import GetCompletionConfigRequest +from .types.catalog_service import GetDefaultBranchRequest +from .types.catalog_service import GetDefaultBranchResponse +from .types.catalog_service import ListCatalogsRequest +from .types.catalog_service import ListCatalogsResponse +from .types.catalog_service import RemoveCatalogAttributeRequest +from .types.catalog_service import ReplaceCatalogAttributeRequest +from .types.catalog_service import SetDefaultBranchRequest +from .types.catalog_service import UpdateAttributesConfigRequest +from .types.catalog_service import UpdateCatalogRequest +from .types.catalog_service import UpdateCompletionConfigRequest +from .types.common import Audience +from .types.common import ColorInfo +from .types.common import Condition +from .types.common import CustomAttribute +from .types.common import FulfillmentInfo +from .types.common import Image +from .types.common import Interval +from .types.common import LocalInventory +from .types.common import PriceInfo +from .types.common import Rating +from .types.common import Rule +from .types.common import UserInfo +from .types.common import AttributeConfigLevel +from .types.common import RecommendationsFilteringOption +from .types.common import SearchSolutionUseCase +from .types.common import SolutionType +from .types.completion_service import CompleteQueryRequest +from .types.completion_service import CompleteQueryResponse +from .types.control import Control +from .types.control_service import CreateControlRequest +from .types.control_service import DeleteControlRequest +from .types.control_service import GetControlRequest +from .types.control_service import ListControlsRequest +from .types.control_service import ListControlsResponse +from .types.control_service import UpdateControlRequest +from .types.import_config import BigQuerySource +from .types.import_config import CompletionDataInputConfig +from .types.import_config import GcsSource +from .types.import_config import ImportCompletionDataRequest +from .types.import_config import ImportCompletionDataResponse +from .types.import_config import ImportErrorsConfig +from .types.import_config import ImportMetadata +from .types.import_config import ImportProductsRequest +from .types.import_config import ImportProductsResponse +from .types.import_config import ImportUserEventsRequest +from .types.import_config import ImportUserEventsResponse +from .types.import_config import ProductInlineSource +from .types.import_config import ProductInputConfig +from .types.import_config import UserEventImportSummary +from .types.import_config import UserEventInlineSource +from .types.import_config import UserEventInputConfig +from .types.model import Model +from .types.model_service import CreateModelMetadata +from .types.model_service import CreateModelRequest +from .types.model_service import DeleteModelRequest +from .types.model_service import GetModelRequest +from .types.model_service import ListModelsRequest +from .types.model_service import ListModelsResponse +from .types.model_service import PauseModelRequest +from .types.model_service import ResumeModelRequest +from .types.model_service import TuneModelMetadata +from .types.model_service import TuneModelRequest +from .types.model_service import TuneModelResponse +from .types.model_service import UpdateModelRequest +from .types.prediction_service import PredictRequest +from .types.prediction_service import PredictResponse +from .types.product import Product +from .types.product_service import AddFulfillmentPlacesMetadata +from .types.product_service import AddFulfillmentPlacesRequest +from .types.product_service import AddFulfillmentPlacesResponse +from .types.product_service import AddLocalInventoriesMetadata +from .types.product_service import AddLocalInventoriesRequest +from .types.product_service import AddLocalInventoriesResponse +from .types.product_service import CreateProductRequest +from .types.product_service import DeleteProductRequest +from .types.product_service import GetProductRequest +from .types.product_service import ListProductsRequest +from .types.product_service import ListProductsResponse +from .types.product_service import RemoveFulfillmentPlacesMetadata +from .types.product_service import RemoveFulfillmentPlacesRequest +from .types.product_service import RemoveFulfillmentPlacesResponse +from .types.product_service import RemoveLocalInventoriesMetadata +from .types.product_service import RemoveLocalInventoriesRequest +from .types.product_service import RemoveLocalInventoriesResponse +from .types.product_service import SetInventoryMetadata +from .types.product_service import SetInventoryRequest +from .types.product_service import SetInventoryResponse +from .types.product_service import UpdateProductRequest +from .types.promotion import Promotion +from .types.purge_config import PurgeMetadata +from .types.purge_config import PurgeUserEventsRequest +from .types.purge_config import PurgeUserEventsResponse +from .types.search_service import ExperimentInfo +from .types.search_service import SearchRequest +from .types.search_service import SearchResponse +from .types.serving_config import ServingConfig +from .types.serving_config_service import AddControlRequest +from .types.serving_config_service import CreateServingConfigRequest +from .types.serving_config_service import DeleteServingConfigRequest +from .types.serving_config_service import GetServingConfigRequest +from .types.serving_config_service import ListServingConfigsRequest +from .types.serving_config_service import ListServingConfigsResponse +from .types.serving_config_service import RemoveControlRequest +from .types.serving_config_service import UpdateServingConfigRequest +from .types.user_event import CompletionDetail +from .types.user_event import ProductDetail +from .types.user_event import PurchaseTransaction +from .types.user_event import UserEvent +from .types.user_event_service import CollectUserEventRequest +from .types.user_event_service import RejoinUserEventsMetadata +from .types.user_event_service import RejoinUserEventsRequest +from .types.user_event_service import RejoinUserEventsResponse +from .types.user_event_service import WriteUserEventRequest + +__all__ = ( + 'CatalogServiceAsyncClient', + 'CompletionServiceAsyncClient', + 'ControlServiceAsyncClient', + 'ModelServiceAsyncClient', + 'PredictionServiceAsyncClient', + 'ProductServiceAsyncClient', + 'SearchServiceAsyncClient', + 'ServingConfigServiceAsyncClient', + 'UserEventServiceAsyncClient', +'AddCatalogAttributeRequest', +'AddControlRequest', +'AddFulfillmentPlacesMetadata', +'AddFulfillmentPlacesRequest', +'AddFulfillmentPlacesResponse', +'AddLocalInventoriesMetadata', +'AddLocalInventoriesRequest', +'AddLocalInventoriesResponse', +'AttributeConfigLevel', +'AttributesConfig', +'Audience', +'BigQuerySource', +'Catalog', +'CatalogAttribute', +'CatalogServiceClient', +'CollectUserEventRequest', +'ColorInfo', +'CompleteQueryRequest', +'CompleteQueryResponse', +'CompletionConfig', +'CompletionDataInputConfig', +'CompletionDetail', +'CompletionServiceClient', +'Condition', +'Control', +'ControlServiceClient', +'CreateControlRequest', +'CreateModelMetadata', +'CreateModelRequest', +'CreateProductRequest', +'CreateServingConfigRequest', +'CustomAttribute', +'DeleteControlRequest', +'DeleteModelRequest', +'DeleteProductRequest', +'DeleteServingConfigRequest', +'ExperimentInfo', +'FulfillmentInfo', +'GcsSource', +'GetAttributesConfigRequest', +'GetCompletionConfigRequest', +'GetControlRequest', +'GetDefaultBranchRequest', +'GetDefaultBranchResponse', +'GetModelRequest', +'GetProductRequest', +'GetServingConfigRequest', +'Image', +'ImportCompletionDataRequest', +'ImportCompletionDataResponse', +'ImportErrorsConfig', +'ImportMetadata', +'ImportProductsRequest', +'ImportProductsResponse', +'ImportUserEventsRequest', +'ImportUserEventsResponse', +'Interval', +'ListCatalogsRequest', +'ListCatalogsResponse', +'ListControlsRequest', +'ListControlsResponse', +'ListModelsRequest', +'ListModelsResponse', +'ListProductsRequest', +'ListProductsResponse', +'ListServingConfigsRequest', +'ListServingConfigsResponse', +'LocalInventory', +'Model', +'ModelServiceClient', +'PauseModelRequest', +'PredictRequest', +'PredictResponse', +'PredictionServiceClient', +'PriceInfo', +'Product', +'ProductDetail', +'ProductInlineSource', +'ProductInputConfig', +'ProductLevelConfig', +'ProductServiceClient', +'Promotion', +'PurchaseTransaction', +'PurgeMetadata', +'PurgeUserEventsRequest', +'PurgeUserEventsResponse', +'Rating', +'RecommendationsFilteringOption', +'RejoinUserEventsMetadata', +'RejoinUserEventsRequest', +'RejoinUserEventsResponse', +'RemoveCatalogAttributeRequest', +'RemoveControlRequest', +'RemoveFulfillmentPlacesMetadata', +'RemoveFulfillmentPlacesRequest', +'RemoveFulfillmentPlacesResponse', +'RemoveLocalInventoriesMetadata', +'RemoveLocalInventoriesRequest', +'RemoveLocalInventoriesResponse', +'ReplaceCatalogAttributeRequest', +'ResumeModelRequest', +'Rule', +'SearchRequest', +'SearchResponse', +'SearchServiceClient', +'SearchSolutionUseCase', +'ServingConfig', +'ServingConfigServiceClient', +'SetDefaultBranchRequest', +'SetInventoryMetadata', +'SetInventoryRequest', +'SetInventoryResponse', +'SolutionType', +'TuneModelMetadata', +'TuneModelRequest', +'TuneModelResponse', +'UpdateAttributesConfigRequest', +'UpdateCatalogRequest', +'UpdateCompletionConfigRequest', +'UpdateControlRequest', +'UpdateModelRequest', +'UpdateProductRequest', +'UpdateServingConfigRequest', +'UserEvent', +'UserEventImportSummary', +'UserEventInlineSource', +'UserEventInputConfig', +'UserEventServiceClient', +'UserInfo', +'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json b/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json new file mode 100644 index 00000000..8130fa01 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/gapic_metadata.json @@ -0,0 +1,945 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.retail_v2", + "protoPackage": "google.cloud.retail.v2", + "schema": "1.0", + "services": { + "CatalogService": { + "clients": { + "grpc": { + "libraryClient": "CatalogServiceClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CatalogServiceAsyncClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + }, + "rest": { + "libraryClient": "CatalogServiceClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + } + } + }, + "CompletionService": { + "clients": { + "grpc": { + "libraryClient": "CompletionServiceClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CompletionServiceAsyncClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + }, + "rest": { + "libraryClient": "CompletionServiceClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + } + } + }, + "ControlService": { + "clients": { + "grpc": { + "libraryClient": "ControlServiceClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ControlServiceAsyncClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + }, + "rest": { + "libraryClient": "ControlServiceClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + } + } + }, + "ModelService": { + "clients": { + "grpc": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ModelServiceAsyncClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "rest": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + } + } + }, + "PredictionService": { + "clients": { + "grpc": { + "libraryClient": "PredictionServiceClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + }, + "grpc-async": { + "libraryClient": "PredictionServiceAsyncClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + }, + "rest": { + "libraryClient": "PredictionServiceClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + } + } + }, + "ProductService": { + "clients": { + "grpc": { + "libraryClient": "ProductServiceClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ProductServiceAsyncClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + }, + "rest": { + "libraryClient": "ProductServiceClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + } + } + }, + "SearchService": { + "clients": { + "grpc": { + "libraryClient": "SearchServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "grpc-async": { + "libraryClient": "SearchServiceAsyncClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "rest": { + "libraryClient": "SearchServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + } + } + }, + "ServingConfigService": { + "clients": { + "grpc": { + "libraryClient": "ServingConfigServiceClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ServingConfigServiceAsyncClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + }, + "rest": { + "libraryClient": "ServingConfigServiceClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + } + } + }, + "UserEventService": { + "clients": { + "grpc": { + "libraryClient": "UserEventServiceClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + }, + "grpc-async": { + "libraryClient": "UserEventServiceAsyncClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + }, + "rest": { + "libraryClient": "UserEventServiceClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/gapic_version.py b/owl-bot-staging/v2/google/cloud/retail_v2/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/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/v2/google/cloud/retail_v2/py.typed b/owl-bot-staging/v2/google/cloud/retail_v2/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/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/v2/google/cloud/retail_v2/services/catalog_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__init__.py new file mode 100644 index 00000000..339851f1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/__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 CatalogServiceClient +from .async_client import CatalogServiceAsyncClient + +__all__ = ( + 'CatalogServiceClient', + 'CatalogServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py new file mode 100644 index 00000000..5d5ec9ee --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/async_client.py @@ -0,0 +1,1522 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.catalog_service import pagers +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .client import CatalogServiceClient + + +class CatalogServiceAsyncClient: + """Service for managing catalog configuration.""" + + _client: CatalogServiceClient + + DEFAULT_ENDPOINT = CatalogServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CatalogServiceClient.DEFAULT_MTLS_ENDPOINT + + attributes_config_path = staticmethod(CatalogServiceClient.attributes_config_path) + parse_attributes_config_path = staticmethod(CatalogServiceClient.parse_attributes_config_path) + branch_path = staticmethod(CatalogServiceClient.branch_path) + parse_branch_path = staticmethod(CatalogServiceClient.parse_branch_path) + catalog_path = staticmethod(CatalogServiceClient.catalog_path) + parse_catalog_path = staticmethod(CatalogServiceClient.parse_catalog_path) + completion_config_path = staticmethod(CatalogServiceClient.completion_config_path) + parse_completion_config_path = staticmethod(CatalogServiceClient.parse_completion_config_path) + common_billing_account_path = staticmethod(CatalogServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CatalogServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CatalogServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CatalogServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CatalogServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CatalogServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CatalogServiceClient.common_project_path) + parse_common_project_path = staticmethod(CatalogServiceClient.parse_common_project_path) + common_location_path = staticmethod(CatalogServiceClient.common_location_path) + parse_common_location_path = staticmethod(CatalogServiceClient.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: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_info.__func__(CatalogServiceAsyncClient, 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: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_file.__func__(CatalogServiceAsyncClient, 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 CatalogServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CatalogServiceClient).get_transport_class, type(CatalogServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CatalogServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service 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, ~.CatalogServiceTransport]): 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 = CatalogServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def list_catalogs(self, + request: Optional[Union[catalog_service.ListCatalogsRequest, 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.ListCatalogsAsyncPager: + r"""Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + .. 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 retail_v2 + + async def sample_list_catalogs(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ListCatalogsRequest, dict]]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + parent (:class:`str`): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2.Catalog]s under this + location, regardless of whether or not this location + exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2.services.catalog_service.pagers.ListCatalogsAsyncPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + 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 = catalog_service.ListCatalogsRequest(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_catalogs, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListCatalogsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_catalog(self, + request: Optional[Union[catalog_service.UpdateCatalogRequest, dict]] = None, + *, + catalog: Optional[gcr_catalog.Catalog] = 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]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + .. 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 retail_v2 + + async def sample_update_catalog(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog = retail_v2.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = await client.update_catalog(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateCatalogRequest, dict]]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] + method. + catalog (:class:`google.cloud.retail_v2.types.Catalog`): + Required. The [Catalog][google.cloud.retail.v2.Catalog] + to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2.Catalog], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + 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.retail_v2.types.Catalog: + The catalog configuration. + """ + # 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([catalog, 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 = catalog_service.UpdateCatalogRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + 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_catalog, + 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(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def set_default_branch(self, + request: Optional[Union[catalog_service.SetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + .. 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 retail_v2 + + async def sample_set_default_branch(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.SetDefaultBranchRequest( + ) + + # Make the request + await client.set_default_branch(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.SetDefaultBranchRequest, dict]]): + The request object. Request message to set a specified branch as new + default_branch. + catalog (:class:`str`): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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([catalog]) + 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 = catalog_service.SetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_default_branch(self, + request: Optional[Union[catalog_service.GetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + .. 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 retail_v2 + + async def sample_get_default_branch(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetDefaultBranchRequest( + ) + + # Make the request + response = await client.get_default_branch(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.GetDefaultBranchRequest, dict]]): + The request object. Request message to show which branch + is currently the default branch. + catalog (:class:`str`): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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.retail_v2.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. + + """ + # 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([catalog]) + 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 = catalog_service.GetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # 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_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_completion_config(self, + request: Optional[Union[catalog_service.GetCompletionConfigRequest, 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]] = (), + ) -> catalog.CompletionConfig: + r"""Gets a + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]. + + .. 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 retail_v2 + + async def sample_get_completion_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.GetCompletionConfigRequest, dict]]): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2.CatalogService.GetCompletionConfig] + method. + name (:class:`str`): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + + 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.retail_v2.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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 = catalog_service.GetCompletionConfigRequest(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_completion_config, + 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(( + ("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_completion_config(self, + request: Optional[Union[catalog_service.UpdateCompletionConfigRequest, dict]] = None, + *, + completion_config: Optional[catalog.CompletionConfig] = 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]] = (), + ) -> catalog.CompletionConfig: + r"""Updates the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]s. + + .. 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 retail_v2 + + async def sample_update_completion_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + completion_config = retail_v2.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = await client.update_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateCompletionConfigRequest, dict]]): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2.CatalogService.UpdateCompletionConfig] + method. + completion_config (:class:`google.cloud.retail_v2.types.CompletionConfig`): + Required. The + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``completion_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + + 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.retail_v2.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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([completion_config, 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 = catalog_service.UpdateCompletionConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if completion_config is not None: + request.completion_config = completion_config + 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_completion_config, + 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(( + ("completion_config.name", request.completion_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_attributes_config(self, + request: Optional[Union[catalog_service.GetAttributesConfigRequest, 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]] = (), + ) -> catalog.AttributesConfig: + r"""Gets an + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + .. 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 retail_v2 + + async def sample_get_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.GetAttributesConfigRequest, dict]]): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2.CatalogService.GetAttributesConfig] + method. + name (:class:`str`): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + + 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.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # 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 = catalog_service.GetAttributesConfigRequest(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_attributes_config, + 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(( + ("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_attributes_config(self, + request: Optional[Union[catalog_service.UpdateAttributesConfigRequest, dict]] = None, + *, + attributes_config: Optional[catalog.AttributesConfig] = 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]] = (), + ) -> catalog.AttributesConfig: + r"""Updates the + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + .. 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 retail_v2 + + async def sample_update_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + attributes_config = retail_v2.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = await client.update_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateAttributesConfigRequest, dict]]): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2.CatalogService.UpdateAttributesConfig] + method. + attributes_config (:class:`google.cloud.retail_v2.types.AttributesConfig`): + Required. The + [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + to update. + + This corresponds to the ``attributes_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + + 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.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # 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([attributes_config, 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 = catalog_service.UpdateAttributesConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if attributes_config is not None: + request.attributes_config = attributes_config + 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_attributes_config, + 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(( + ("attributes_config.name", request.attributes_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_catalog_attribute(self, + request: Optional[Union[catalog_service.AddCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Adds the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + add already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2 + + async def sample_add_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.AddCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2.CatalogService.AddCatalogAttribute] + 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: + google.cloud.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.AddCatalogAttributeRequest(request) + + # 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_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_catalog_attribute(self, + request: Optional[Union[catalog_service.RemoveCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Removes the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] from + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + remove does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + async def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = await client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.RemoveCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute] + 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: + google.cloud.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.RemoveCatalogAttributeRequest(request) + + # 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_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def replace_catalog_attribute(self, + request: Optional[Union[catalog_service.ReplaceCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Replaces the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] in + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + replace does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + async def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ReplaceCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute] + 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: + google.cloud.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.ReplaceCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.replace_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CatalogServiceAsyncClient": + 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__ = ( + "CatalogServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py new file mode 100644 index 00000000..9160144e --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/client.py @@ -0,0 +1,1759 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.catalog_service import pagers +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CatalogServiceGrpcTransport +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .transports.rest import CatalogServiceRestTransport + + +class CatalogServiceClientMeta(type): + """Metaclass for the CatalogService 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[CatalogServiceTransport]] + _transport_registry["grpc"] = CatalogServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CatalogServiceGrpcAsyncIOTransport + _transport_registry["rest"] = CatalogServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[CatalogServiceTransport]: + """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 CatalogServiceClient(metaclass=CatalogServiceClientMeta): + """Service for managing catalog configuration.""" + + @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 = "retail.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: + CatalogServiceClient: 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: + CatalogServiceClient: 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) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def attributes_config_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified attributes_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/attributesConfig".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_attributes_config_path(path: str) -> Dict[str,str]: + """Parses a attributes_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/attributesConfig$", path) + return m.groupdict() if m else {} + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def completion_config_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified completion_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/completionConfig".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_completion_config_path(path: str) -> Dict[str,str]: + """Parses a completion_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/completionConfig$", 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, CatalogServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service 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, CatalogServiceTransport]): 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, CatalogServiceTransport): + # transport is a CatalogServiceTransport 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 list_catalogs(self, + request: Optional[Union[catalog_service.ListCatalogsRequest, 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.ListCatalogsPager: + r"""Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + .. 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 retail_v2 + + def sample_list_catalogs(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ListCatalogsRequest, dict]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2.Catalog]s under this + location, regardless of whether or not this location + exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2.services.catalog_service.pagers.ListCatalogsPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + 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 catalog_service.ListCatalogsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.ListCatalogsRequest): + request = catalog_service.ListCatalogsRequest(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_catalogs] + + # 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.ListCatalogsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_catalog(self, + request: Optional[Union[catalog_service.UpdateCatalogRequest, dict]] = None, + *, + catalog: Optional[gcr_catalog.Catalog] = 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]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + .. 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 retail_v2 + + def sample_update_catalog(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + catalog = retail_v2.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = client.update_catalog(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateCatalogRequest, dict]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] + method. + catalog (google.cloud.retail_v2.types.Catalog): + Required. The [Catalog][google.cloud.retail.v2.Catalog] + to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2.Catalog], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + 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.retail_v2.types.Catalog: + The catalog configuration. + """ + # 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([catalog, 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 catalog_service.UpdateCatalogRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateCatalogRequest): + request = catalog_service.UpdateCatalogRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + 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_catalog] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def set_default_branch(self, + request: Optional[Union[catalog_service.SetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + .. 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 retail_v2 + + def sample_set_default_branch(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.SetDefaultBranchRequest( + ) + + # Make the request + client.set_default_branch(request=request) + + Args: + request (Union[google.cloud.retail_v2.types.SetDefaultBranchRequest, dict]): + The request object. Request message to set a specified branch as new + default_branch. + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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([catalog]) + 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 catalog_service.SetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.SetDefaultBranchRequest): + request = catalog_service.SetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_default_branch(self, + request: Optional[Union[catalog_service.GetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + .. 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 retail_v2 + + def sample_get_default_branch(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetDefaultBranchRequest( + ) + + # Make the request + response = client.get_default_branch(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetDefaultBranchRequest, dict]): + The request object. Request message to show which branch + is currently the default branch. + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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.retail_v2.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. + + """ + # 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([catalog]) + 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 catalog_service.GetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetDefaultBranchRequest): + request = catalog_service.GetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_completion_config(self, + request: Optional[Union[catalog_service.GetCompletionConfigRequest, 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]] = (), + ) -> catalog.CompletionConfig: + r"""Gets a + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]. + + .. 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 retail_v2 + + def sample_get_completion_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetCompletionConfigRequest, dict]): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2.CatalogService.GetCompletionConfig] + method. + name (str): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + + 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.retail_v2.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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 catalog_service.GetCompletionConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetCompletionConfigRequest): + request = catalog_service.GetCompletionConfigRequest(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_completion_config] + + # 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_completion_config(self, + request: Optional[Union[catalog_service.UpdateCompletionConfigRequest, dict]] = None, + *, + completion_config: Optional[catalog.CompletionConfig] = 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]] = (), + ) -> catalog.CompletionConfig: + r"""Updates the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]s. + + .. 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 retail_v2 + + def sample_update_completion_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + completion_config = retail_v2.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = client.update_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateCompletionConfigRequest, dict]): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2.CatalogService.UpdateCompletionConfig] + method. + completion_config (google.cloud.retail_v2.types.CompletionConfig): + Required. The + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``completion_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + + 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.retail_v2.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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([completion_config, 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 catalog_service.UpdateCompletionConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateCompletionConfigRequest): + request = catalog_service.UpdateCompletionConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if completion_config is not None: + request.completion_config = completion_config + 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_completion_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("completion_config.name", request.completion_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_attributes_config(self, + request: Optional[Union[catalog_service.GetAttributesConfigRequest, 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]] = (), + ) -> catalog.AttributesConfig: + r"""Gets an + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + .. 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 retail_v2 + + def sample_get_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetAttributesConfigRequest, dict]): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2.CatalogService.GetAttributesConfig] + method. + name (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + + 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.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # 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 catalog_service.GetAttributesConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetAttributesConfigRequest): + request = catalog_service.GetAttributesConfigRequest(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_attributes_config] + + # 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_attributes_config(self, + request: Optional[Union[catalog_service.UpdateAttributesConfigRequest, dict]] = None, + *, + attributes_config: Optional[catalog.AttributesConfig] = 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]] = (), + ) -> catalog.AttributesConfig: + r"""Updates the + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + .. 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 retail_v2 + + def sample_update_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + attributes_config = retail_v2.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = client.update_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateAttributesConfigRequest, dict]): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2.CatalogService.UpdateAttributesConfig] + method. + attributes_config (google.cloud.retail_v2.types.AttributesConfig): + Required. The + [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + to update. + + This corresponds to the ``attributes_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + + 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.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # 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([attributes_config, 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 catalog_service.UpdateAttributesConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateAttributesConfigRequest): + request = catalog_service.UpdateAttributesConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if attributes_config is not None: + request.attributes_config = attributes_config + 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_attributes_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config.name", request.attributes_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_catalog_attribute(self, + request: Optional[Union[catalog_service.AddCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Adds the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + add already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2 + + def sample_add_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.AddCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2.CatalogService.AddCatalogAttribute] + 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: + google.cloud.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.AddCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.AddCatalogAttributeRequest): + request = catalog_service.AddCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_catalog_attribute(self, + request: Optional[Union[catalog_service.RemoveCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Removes the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] from + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + remove does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.RemoveCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute] + 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: + google.cloud.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.RemoveCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.RemoveCatalogAttributeRequest): + request = catalog_service.RemoveCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def replace_catalog_attribute(self, + request: Optional[Union[catalog_service.ReplaceCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Replaces the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] in + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + replace does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ReplaceCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute] + 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: + google.cloud.retail_v2.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.ReplaceCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.ReplaceCatalogAttributeRequest): + request = catalog_service.ReplaceCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.replace_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CatalogServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "CatalogServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py new file mode 100644 index 00000000..15c79c4b --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog_service + + +class ListCatalogsPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListCatalogsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListCatalogsResponse` + 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[..., catalog_service.ListCatalogsResponse], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + 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.retail_v2.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListCatalogsResponse): + 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 = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[catalog_service.ListCatalogsResponse]: + 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[catalog.Catalog]: + for page in self.pages: + yield from page.catalogs + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListCatalogsAsyncPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListCatalogsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListCatalogsResponse` + 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[catalog_service.ListCatalogsResponse]], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + 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.retail_v2.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListCatalogsResponse): + 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 = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[catalog_service.ListCatalogsResponse]: + 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[catalog.Catalog]: + async def async_generator(): + async for page in self.pages: + for response in page.catalogs: + 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/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/__init__.py new file mode 100644 index 00000000..12110418 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/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 CatalogServiceTransport +from .grpc import CatalogServiceGrpcTransport +from .grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .rest import CatalogServiceRestTransport +from .rest import CatalogServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CatalogServiceTransport]] +_transport_registry['grpc'] = CatalogServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CatalogServiceGrpcAsyncIOTransport +_transport_registry['rest'] = CatalogServiceRestTransport + +__all__ = ( + 'CatalogServiceTransport', + 'CatalogServiceGrpcTransport', + 'CatalogServiceGrpcAsyncIOTransport', + 'CatalogServiceRestTransport', + 'CatalogServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py new file mode 100644 index 00000000..e9588684 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/base.py @@ -0,0 +1,311 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_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 CatalogServiceTransport(abc.ABC): + """Abstract transport class for CatalogService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.list_catalogs: gapic_v1.method.wrap_method( + self.list_catalogs, + default_timeout=None, + client_info=client_info, + ), + self.update_catalog: gapic_v1.method.wrap_method( + self.update_catalog, + default_timeout=None, + client_info=client_info, + ), + self.set_default_branch: gapic_v1.method.wrap_method( + self.set_default_branch, + default_timeout=None, + client_info=client_info, + ), + self.get_default_branch: gapic_v1.method.wrap_method( + self.get_default_branch, + default_timeout=None, + client_info=client_info, + ), + self.get_completion_config: gapic_v1.method.wrap_method( + self.get_completion_config, + default_timeout=None, + client_info=client_info, + ), + self.update_completion_config: gapic_v1.method.wrap_method( + self.update_completion_config, + default_timeout=None, + client_info=client_info, + ), + self.get_attributes_config: gapic_v1.method.wrap_method( + self.get_attributes_config, + default_timeout=None, + client_info=client_info, + ), + self.update_attributes_config: gapic_v1.method.wrap_method( + self.update_attributes_config, + default_timeout=None, + client_info=client_info, + ), + self.add_catalog_attribute: gapic_v1.method.wrap_method( + self.add_catalog_attribute, + default_timeout=None, + client_info=client_info, + ), + self.remove_catalog_attribute: gapic_v1.method.wrap_method( + self.remove_catalog_attribute, + default_timeout=None, + client_info=client_info, + ), + self.replace_catalog_attribute: gapic_v1.method.wrap_method( + self.replace_catalog_attribute, + 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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Union[ + catalog_service.ListCatalogsResponse, + Awaitable[catalog_service.ListCatalogsResponse] + ]]: + raise NotImplementedError() + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Union[ + gcr_catalog.Catalog, + Awaitable[gcr_catalog.Catalog] + ]]: + raise NotImplementedError() + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Union[ + catalog_service.GetDefaultBranchResponse, + Awaitable[catalog_service.GetDefaultBranchResponse] + ]]: + raise NotImplementedError() + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + Union[ + catalog.CompletionConfig, + Awaitable[catalog.CompletionConfig] + ]]: + raise NotImplementedError() + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + Union[ + catalog.CompletionConfig, + Awaitable[catalog.CompletionConfig] + ]]: + raise NotImplementedError() + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'CatalogServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py new file mode 100644 index 00000000..fca93da0 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc.py @@ -0,0 +1,635 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO + + +class CatalogServiceGrpcTransport(CatalogServiceTransport): + """gRPC backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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 = 'retail.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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + catalog_service.ListCatalogsResponse]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + ~.ListCatalogsResponse]: + 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_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + gcr_catalog.Catalog]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + ~.Catalog]: + 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_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + empty_pb2.Empty]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + Returns: + Callable[[~.SetDefaultBranchRequest], + ~.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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + catalog_service.GetDefaultBranchResponse]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + Returns: + Callable[[~.GetDefaultBranchRequest], + ~.GetDefaultBranchResponse]: + 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_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + catalog.CompletionConfig]: + r"""Return a callable for the get completion config method over gRPC. + + Gets a + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]. + + Returns: + Callable[[~.GetCompletionConfigRequest], + ~.CompletionConfig]: + 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_completion_config' not in self._stubs: + self._stubs['get_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetCompletionConfig', + request_serializer=catalog_service.GetCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['get_completion_config'] + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + catalog.CompletionConfig]: + r"""Return a callable for the update completion config method over gRPC. + + Updates the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]s. + + Returns: + Callable[[~.UpdateCompletionConfigRequest], + ~.CompletionConfig]: + 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_completion_config' not in self._stubs: + self._stubs['update_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateCompletionConfig', + request_serializer=catalog_service.UpdateCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['update_completion_config'] + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + catalog.AttributesConfig]: + r"""Return a callable for the get attributes config method over gRPC. + + Gets an + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + Returns: + Callable[[~.GetAttributesConfigRequest], + ~.AttributesConfig]: + 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_attributes_config' not in self._stubs: + self._stubs['get_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetAttributesConfig', + request_serializer=catalog_service.GetAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['get_attributes_config'] + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + catalog.AttributesConfig]: + r"""Return a callable for the update attributes config method over gRPC. + + Updates the + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + Returns: + Callable[[~.UpdateAttributesConfigRequest], + ~.AttributesConfig]: + 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_attributes_config' not in self._stubs: + self._stubs['update_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateAttributesConfig', + request_serializer=catalog_service.UpdateAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['update_attributes_config'] + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the add catalog attribute method over gRPC. + + Adds the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + add already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.AddCatalogAttributeRequest], + ~.AttributesConfig]: + 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_catalog_attribute' not in self._stubs: + self._stubs['add_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/AddCatalogAttribute', + request_serializer=catalog_service.AddCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['add_catalog_attribute'] + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the remove catalog attribute method over gRPC. + + Removes the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] from + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + remove does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.RemoveCatalogAttributeRequest], + ~.AttributesConfig]: + 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_catalog_attribute' not in self._stubs: + self._stubs['remove_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/RemoveCatalogAttribute', + request_serializer=catalog_service.RemoveCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['remove_catalog_attribute'] + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the replace catalog attribute method over gRPC. + + Replaces the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] in + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + replace does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.ReplaceCatalogAttributeRequest], + ~.AttributesConfig]: + 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 'replace_catalog_attribute' not in self._stubs: + self._stubs['replace_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/ReplaceCatalogAttribute', + request_serializer=catalog_service.ReplaceCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['replace_catalog_attribute'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'CatalogServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..8b4b0ef2 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/grpc_asyncio.py @@ -0,0 +1,634 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CatalogServiceGrpcTransport + + +class CatalogServiceGrpcAsyncIOTransport(CatalogServiceTransport): + """gRPC AsyncIO backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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 = 'retail.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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Awaitable[catalog_service.ListCatalogsResponse]]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + Awaitable[~.ListCatalogsResponse]]: + 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_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Awaitable[gcr_catalog.Catalog]]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + Awaitable[~.Catalog]]: + 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_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + Returns: + Callable[[~.SetDefaultBranchRequest], + 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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Awaitable[catalog_service.GetDefaultBranchResponse]]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + Returns: + Callable[[~.GetDefaultBranchRequest], + Awaitable[~.GetDefaultBranchResponse]]: + 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_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + Awaitable[catalog.CompletionConfig]]: + r"""Return a callable for the get completion config method over gRPC. + + Gets a + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]. + + Returns: + Callable[[~.GetCompletionConfigRequest], + Awaitable[~.CompletionConfig]]: + 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_completion_config' not in self._stubs: + self._stubs['get_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetCompletionConfig', + request_serializer=catalog_service.GetCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['get_completion_config'] + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + Awaitable[catalog.CompletionConfig]]: + r"""Return a callable for the update completion config method over gRPC. + + Updates the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig]s. + + Returns: + Callable[[~.UpdateCompletionConfigRequest], + Awaitable[~.CompletionConfig]]: + 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_completion_config' not in self._stubs: + self._stubs['update_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateCompletionConfig', + request_serializer=catalog_service.UpdateCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['update_completion_config'] + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the get attributes config method over gRPC. + + Gets an + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + Returns: + Callable[[~.GetAttributesConfigRequest], + Awaitable[~.AttributesConfig]]: + 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_attributes_config' not in self._stubs: + self._stubs['get_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/GetAttributesConfig', + request_serializer=catalog_service.GetAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['get_attributes_config'] + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the update attributes config method over gRPC. + + Updates the + [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + Returns: + Callable[[~.UpdateAttributesConfigRequest], + Awaitable[~.AttributesConfig]]: + 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_attributes_config' not in self._stubs: + self._stubs['update_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/UpdateAttributesConfig', + request_serializer=catalog_service.UpdateAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['update_attributes_config'] + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the add catalog attribute method over gRPC. + + Adds the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + add already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.AddCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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_catalog_attribute' not in self._stubs: + self._stubs['add_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/AddCatalogAttribute', + request_serializer=catalog_service.AddCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['add_catalog_attribute'] + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the remove catalog attribute method over gRPC. + + Removes the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] from + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + remove does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.RemoveCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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_catalog_attribute' not in self._stubs: + self._stubs['remove_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/RemoveCatalogAttribute', + request_serializer=catalog_service.RemoveCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['remove_catalog_attribute'] + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the replace catalog attribute method over gRPC. + + Replaces the specified + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] in + the [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] to + replace does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.ReplaceCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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 'replace_catalog_attribute' not in self._stubs: + self._stubs['replace_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CatalogService/ReplaceCatalogAttribute', + request_serializer=catalog_service.ReplaceCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['replace_catalog_attribute'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'CatalogServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/rest.py new file mode 100644 index 00000000..e6bd5f3b --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/catalog_service/transports/rest.py @@ -0,0 +1,1638 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import CatalogServiceTransport, 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 CatalogServiceRestInterceptor: + """Interceptor for CatalogService. + + 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 CatalogServiceRestTransport. + + .. code-block:: python + class MyCustomCatalogServiceInterceptor(CatalogServiceRestInterceptor): + def pre_add_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_attributes_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_attributes_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_completion_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_completion_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_default_branch(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_default_branch(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_catalogs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_catalogs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_replace_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_replace_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_default_branch(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_update_attributes_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_attributes_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_catalog(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_catalog(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_completion_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_completion_config(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CatalogServiceRestTransport(interceptor=MyCustomCatalogServiceInterceptor()) + client = CatalogServiceClient(transport=transport) + + + """ + def pre_add_catalog_attribute(self, request: catalog_service.AddCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.AddCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_add_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for add_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_attributes_config(self, request: catalog_service.GetAttributesConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetAttributesConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_attributes_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_attributes_config(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for get_attributes_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_completion_config(self, request: catalog_service.GetCompletionConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetCompletionConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_completion_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_completion_config(self, response: catalog.CompletionConfig) -> catalog.CompletionConfig: + """Post-rpc interceptor for get_completion_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_default_branch(self, request: catalog_service.GetDefaultBranchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetDefaultBranchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_default_branch + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_default_branch(self, response: catalog_service.GetDefaultBranchResponse) -> catalog_service.GetDefaultBranchResponse: + """Post-rpc interceptor for get_default_branch + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_list_catalogs(self, request: catalog_service.ListCatalogsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.ListCatalogsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_catalogs + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_list_catalogs(self, response: catalog_service.ListCatalogsResponse) -> catalog_service.ListCatalogsResponse: + """Post-rpc interceptor for list_catalogs + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_remove_catalog_attribute(self, request: catalog_service.RemoveCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.RemoveCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_remove_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for remove_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_replace_catalog_attribute(self, request: catalog_service.ReplaceCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.ReplaceCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for replace_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_replace_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for replace_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_set_default_branch(self, request: catalog_service.SetDefaultBranchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.SetDefaultBranchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_default_branch + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def pre_update_attributes_config(self, request: catalog_service.UpdateAttributesConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateAttributesConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_attributes_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_attributes_config(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for update_attributes_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_update_catalog(self, request: catalog_service.UpdateCatalogRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateCatalogRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_catalog + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_catalog(self, response: gcr_catalog.Catalog) -> gcr_catalog.Catalog: + """Post-rpc interceptor for update_catalog + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_update_completion_config(self, request: catalog_service.UpdateCompletionConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateCompletionConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_completion_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_completion_config(self, response: catalog.CompletionConfig) -> catalog.CompletionConfig: + """Post-rpc interceptor for update_completion_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CatalogServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CatalogServiceRestInterceptor + + +class CatalogServiceRestTransport(CatalogServiceTransport): + """REST backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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[CatalogServiceRestInterceptor] = 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 CatalogServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _AddCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("AddCatalogAttribute") + + __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: catalog_service.AddCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the add catalog attribute method over HTTP. + + Args: + request (~.catalog_service.AddCatalogAttributeRequest): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2.CatalogService.AddCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:addCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_catalog_attribute(request, metadata) + pb_request = catalog_service.AddCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_add_catalog_attribute(resp) + return resp + + class _GetAttributesConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("GetAttributesConfig") + + __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: catalog_service.GetAttributesConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the get attributes config method over HTTP. + + Args: + request (~.catalog_service.GetAttributesConfigRequest): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2.CatalogService.GetAttributesConfig] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/attributesConfig}', + }, + ] + request, metadata = self._interceptor.pre_get_attributes_config(request, metadata) + pb_request = catalog_service.GetAttributesConfigRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_attributes_config(resp) + return resp + + class _GetCompletionConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("GetCompletionConfig") + + __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: catalog_service.GetCompletionConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.CompletionConfig: + r"""Call the get completion config method over HTTP. + + Args: + request (~.catalog_service.GetCompletionConfigRequest): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2.CatalogService.GetCompletionConfig] + 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: + ~.catalog.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/completionConfig}', + }, + ] + request, metadata = self._interceptor.pre_get_completion_config(request, metadata) + pb_request = catalog_service.GetCompletionConfigRequest.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 = catalog.CompletionConfig() + pb_resp = catalog.CompletionConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_completion_config(resp) + return resp + + class _GetDefaultBranch(CatalogServiceRestStub): + def __hash__(self): + return hash("GetDefaultBranch") + + def __call__(self, + request: catalog_service.GetDefaultBranchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Call the get default branch method over HTTP. + + Args: + request (~.catalog_service.GetDefaultBranchRequest): + The request object. Request message to show which branch + is currently the default branch. + 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: + ~.catalog_service.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{catalog=projects/*/locations/*/catalogs/*}:getDefaultBranch', + }, + ] + request, metadata = self._interceptor.pre_get_default_branch(request, metadata) + pb_request = catalog_service.GetDefaultBranchRequest.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["$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 = catalog_service.GetDefaultBranchResponse() + pb_resp = catalog_service.GetDefaultBranchResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_default_branch(resp) + return resp + + class _ListCatalogs(CatalogServiceRestStub): + def __hash__(self): + return hash("ListCatalogs") + + __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: catalog_service.ListCatalogsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.ListCatalogsResponse: + r"""Call the list catalogs method over HTTP. + + Args: + request (~.catalog_service.ListCatalogsRequest): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + 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: + ~.catalog_service.ListCatalogsResponse: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{parent=projects/*/locations/*}/catalogs', + }, + ] + request, metadata = self._interceptor.pre_list_catalogs(request, metadata) + pb_request = catalog_service.ListCatalogsRequest.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 = catalog_service.ListCatalogsResponse() + pb_resp = catalog_service.ListCatalogsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_catalogs(resp) + return resp + + class _RemoveCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("RemoveCatalogAttribute") + + __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: catalog_service.RemoveCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the remove catalog attribute method over HTTP. + + Args: + request (~.catalog_service.RemoveCatalogAttributeRequest): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:removeCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_catalog_attribute(request, metadata) + pb_request = catalog_service.RemoveCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_remove_catalog_attribute(resp) + return resp + + class _ReplaceCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("ReplaceCatalogAttribute") + + __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: catalog_service.ReplaceCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the replace catalog attribute method over HTTP. + + Args: + request (~.catalog_service.ReplaceCatalogAttributeRequest): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:replaceCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_replace_catalog_attribute(request, metadata) + pb_request = catalog_service.ReplaceCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_replace_catalog_attribute(resp) + return resp + + class _SetDefaultBranch(CatalogServiceRestStub): + def __hash__(self): + return hash("SetDefaultBranch") + + def __call__(self, + request: catalog_service.SetDefaultBranchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the set default branch method over HTTP. + + Args: + request (~.catalog_service.SetDefaultBranchRequest): + The request object. Request message to set a specified branch as new + default_branch. + 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': '/v2/{catalog=projects/*/locations/*/catalogs/*}:setDefaultBranch', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_set_default_branch(request, metadata) + pb_request = catalog_service.SetDefaultBranchRequest.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["$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 _UpdateAttributesConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateAttributesConfig") + + __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: catalog_service.UpdateAttributesConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the update attributes config method over HTTP. + + Args: + request (~.catalog_service.UpdateAttributesConfigRequest): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2.CatalogService.UpdateAttributesConfig] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2/{attributes_config.name=projects/*/locations/*/catalogs/*/attributesConfig}', + 'body': 'attributes_config', + }, + ] + request, metadata = self._interceptor.pre_update_attributes_config(request, metadata) + pb_request = catalog_service.UpdateAttributesConfigRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_attributes_config(resp) + return resp + + class _UpdateCatalog(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateCatalog") + + __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: catalog_service.UpdateCatalogRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_catalog.Catalog: + r"""Call the update catalog method over HTTP. + + Args: + request (~.catalog_service.UpdateCatalogRequest): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] + 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: + ~.gcr_catalog.Catalog: + The catalog configuration. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2/{catalog.name=projects/*/locations/*/catalogs/*}', + 'body': 'catalog', + }, + ] + request, metadata = self._interceptor.pre_update_catalog(request, metadata) + pb_request = catalog_service.UpdateCatalogRequest.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 = gcr_catalog.Catalog() + pb_resp = gcr_catalog.Catalog.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_catalog(resp) + return resp + + class _UpdateCompletionConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateCompletionConfig") + + __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: catalog_service.UpdateCompletionConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.CompletionConfig: + r"""Call the update completion config method over HTTP. + + Args: + request (~.catalog_service.UpdateCompletionConfigRequest): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2.CatalogService.UpdateCompletionConfig] + 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: + ~.catalog.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2/{completion_config.name=projects/*/locations/*/catalogs/*/completionConfig}', + 'body': 'completion_config', + }, + ] + request, metadata = self._interceptor.pre_update_completion_config(request, metadata) + pb_request = catalog_service.UpdateCompletionConfigRequest.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 = catalog.CompletionConfig() + pb_resp = catalog.CompletionConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_completion_config(resp) + return resp + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._AddCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + catalog.AttributesConfig]: + # 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._GetAttributesConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + catalog.CompletionConfig]: + # 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._GetCompletionConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + catalog_service.GetDefaultBranchResponse]: + # 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._GetDefaultBranch(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + catalog_service.ListCatalogsResponse]: + # 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._ListCatalogs(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._RemoveCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._ReplaceCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + 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._SetDefaultBranch(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + catalog.AttributesConfig]: + # 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._UpdateAttributesConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + gcr_catalog.Catalog]: + # 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._UpdateCatalog(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + catalog.CompletionConfig]: + # 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._UpdateCompletionConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(CatalogServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(CatalogServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'CatalogServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__init__.py new file mode 100644 index 00000000..440cbfb4 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/__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 CompletionServiceClient +from .async_client import CompletionServiceAsyncClient + +__all__ = ( + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py new file mode 100644 index 00000000..8a9fde63 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/async_client.py @@ -0,0 +1,507 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .client import CompletionServiceClient + + +class CompletionServiceAsyncClient: + """Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + _client: CompletionServiceClient + + DEFAULT_ENDPOINT = CompletionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CompletionServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(CompletionServiceClient.catalog_path) + parse_catalog_path = staticmethod(CompletionServiceClient.parse_catalog_path) + common_billing_account_path = staticmethod(CompletionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CompletionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CompletionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CompletionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CompletionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CompletionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CompletionServiceClient.common_project_path) + parse_common_project_path = staticmethod(CompletionServiceClient.parse_common_project_path) + common_location_path = staticmethod(CompletionServiceClient.common_location_path) + parse_common_location_path = staticmethod(CompletionServiceClient.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: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_info.__func__(CompletionServiceAsyncClient, 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: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_file.__func__(CompletionServiceAsyncClient, 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 CompletionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CompletionServiceClient).get_transport_class, type(CompletionServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CompletionServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service 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, ~.CompletionServiceTransport]): 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 = CompletionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def complete_query(self, + request: Optional[Union[completion_service.CompleteQueryRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> completion_service.CompleteQueryResponse: + r"""Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2 + + async def sample_complete_query(): + # Create a client + client = retail_v2.CompletionServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = await client.complete_query(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]]): + The request object. Autocomplete parameters. + 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.retail_v2.types.CompleteQueryResponse: + Response of the autocomplete query. + """ + # Create or coerce a protobuf request object. + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.complete_query, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def import_completion_data(self, + request: Optional[Union[import_config.ImportCompletionDataRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2 + + async def sample_import_completion_data(): + # Create a client + client = retail_v2.CompletionServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ImportCompletionDataRequest, dict]]): + The request object. Request message for + ImportCompletionData methods. + 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.retail_v2.types.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportCompletionDataRequest(request) + + # 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_completion_data, + 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, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CompletionServiceAsyncClient": + 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__ = ( + "CompletionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py new file mode 100644 index 00000000..dc04bb51 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/client.py @@ -0,0 +1,716 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CompletionServiceGrpcTransport +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .transports.rest import CompletionServiceRestTransport + + +class CompletionServiceClientMeta(type): + """Metaclass for the CompletionService 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[CompletionServiceTransport]] + _transport_registry["grpc"] = CompletionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CompletionServiceGrpcAsyncIOTransport + _transport_registry["rest"] = CompletionServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[CompletionServiceTransport]: + """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 CompletionServiceClient(metaclass=CompletionServiceClientMeta): + """Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + @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 = "retail.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: + CompletionServiceClient: 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: + CompletionServiceClient: 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) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?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, CompletionServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service 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, CompletionServiceTransport]): 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, CompletionServiceTransport): + # transport is a CompletionServiceTransport 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 complete_query(self, + request: Optional[Union[completion_service.CompleteQueryRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> completion_service.CompleteQueryResponse: + r"""Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2 + + def sample_complete_query(): + # Create a client + client = retail_v2.CompletionServiceClient() + + # Initialize request argument(s) + request = retail_v2.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = client.complete_query(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.CompleteQueryRequest, dict]): + The request object. Autocomplete parameters. + 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.retail_v2.types.CompleteQueryResponse: + Response of the autocomplete query. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a completion_service.CompleteQueryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, completion_service.CompleteQueryRequest): + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.complete_query] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def import_completion_data(self, + request: Optional[Union[import_config.ImportCompletionDataRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2 + + def sample_import_completion_data(): + # Create a client + client = retail_v2.CompletionServiceClient() + + # Initialize request argument(s) + input_config = retail_v2.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ImportCompletionDataRequest, dict]): + The request object. Request message for + ImportCompletionData methods. + 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.retail_v2.types.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportCompletionDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportCompletionDataRequest): + request = import_config.ImportCompletionDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_completion_data] + + # 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, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CompletionServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "CompletionServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/__init__.py new file mode 100644 index 00000000..f32ad441 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/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 CompletionServiceTransport +from .grpc import CompletionServiceGrpcTransport +from .grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .rest import CompletionServiceRestTransport +from .rest import CompletionServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CompletionServiceTransport]] +_transport_registry['grpc'] = CompletionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CompletionServiceGrpcAsyncIOTransport +_transport_registry['rest'] = CompletionServiceRestTransport + +__all__ = ( + 'CompletionServiceTransport', + 'CompletionServiceGrpcTransport', + 'CompletionServiceGrpcAsyncIOTransport', + 'CompletionServiceRestTransport', + 'CompletionServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py new file mode 100644 index 00000000..a8cfedea --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/base.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class CompletionServiceTransport(abc.ABC): + """Abstract transport class for CompletionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.complete_query: gapic_v1.method.wrap_method( + self.complete_query, + default_timeout=None, + client_info=client_info, + ), + self.import_completion_data: gapic_v1.method.wrap_method( + self.import_completion_data, + 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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Union[ + completion_service.CompleteQueryResponse, + Awaitable[completion_service.CompleteQueryResponse] + ]]: + raise NotImplementedError() + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'CompletionServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py new file mode 100644 index 00000000..0fa54af7 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc.py @@ -0,0 +1,366 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO + + +class CompletionServiceGrpcTransport(CompletionServiceTransport): + """gRPC backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + completion_service.CompleteQueryResponse]: + r"""Return a callable for the complete query method over gRPC. + + Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.CompleteQueryRequest], + ~.CompleteQueryResponse]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + operations_pb2.Operation]: + r"""Return a callable for the import completion data method over gRPC. + + Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.ImportCompletionDataRequest], + ~.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_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'CompletionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..66cd37ff --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/grpc_asyncio.py @@ -0,0 +1,365 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CompletionServiceGrpcTransport + + +class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): + """gRPC AsyncIO backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Awaitable[completion_service.CompleteQueryResponse]]: + r"""Return a callable for the complete query method over gRPC. + + Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.CompleteQueryRequest], + Awaitable[~.CompleteQueryResponse]]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import completion data method over gRPC. + + Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.ImportCompletionDataRequest], + 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_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'CompletionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/rest.py new file mode 100644 index 00000000..6c963609 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/completion_service/transports/rest.py @@ -0,0 +1,666 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore + +from .base import CompletionServiceTransport, 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 CompletionServiceRestInterceptor: + """Interceptor for CompletionService. + + 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 CompletionServiceRestTransport. + + .. code-block:: python + class MyCustomCompletionServiceInterceptor(CompletionServiceRestInterceptor): + def pre_complete_query(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_complete_query(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_completion_data(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_completion_data(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CompletionServiceRestTransport(interceptor=MyCustomCompletionServiceInterceptor()) + client = CompletionServiceClient(transport=transport) + + + """ + def pre_complete_query(self, request: completion_service.CompleteQueryRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[completion_service.CompleteQueryRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for complete_query + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_complete_query(self, response: completion_service.CompleteQueryResponse) -> completion_service.CompleteQueryResponse: + """Post-rpc interceptor for complete_query + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + def pre_import_completion_data(self, request: import_config.ImportCompletionDataRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportCompletionDataRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_completion_data + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_import_completion_data(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_completion_data + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CompletionServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CompletionServiceRestInterceptor + + +class CompletionServiceRestTransport(CompletionServiceTransport): + """REST backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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[CompletionServiceRestInterceptor] = 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 CompletionServiceRestInterceptor() + 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': '/v2/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*}/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="v2") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CompleteQuery(CompletionServiceRestStub): + def __hash__(self): + return hash("CompleteQuery") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "query" : "", } + + @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: completion_service.CompleteQueryRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> completion_service.CompleteQueryResponse: + r"""Call the complete query method over HTTP. + + Args: + request (~.completion_service.CompleteQueryRequest): + The request object. Autocomplete parameters. + 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: + ~.completion_service.CompleteQueryResponse: + Response of the autocomplete query. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{catalog=projects/*/locations/*/catalogs/*}:completeQuery', + }, + ] + request, metadata = self._interceptor.pre_complete_query(request, metadata) + pb_request = completion_service.CompleteQueryRequest.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 = completion_service.CompleteQueryResponse() + pb_resp = completion_service.CompleteQueryResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_complete_query(resp) + return resp + + class _ImportCompletionData(CompletionServiceRestStub): + def __hash__(self): + return hash("ImportCompletionData") + + __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: import_config.ImportCompletionDataRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import completion data method over HTTP. + + Args: + request (~.import_config.ImportCompletionDataRequest): + The request object. Request message for + ImportCompletionData methods. + 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': '/v2/{parent=projects/*/locations/*/catalogs/*}/completionData:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_completion_data(request, metadata) + pb_request = import_config.ImportCompletionDataRequest.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_completion_data(resp) + return resp + + @property + def complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + completion_service.CompleteQueryResponse]: + # 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._CompleteQuery(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + 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._ImportCompletionData(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(CompletionServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(CompletionServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'CompletionServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/__init__.py new file mode 100644 index 00000000..b5539469 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/__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 ControlServiceClient +from .async_client import ControlServiceAsyncClient + +__all__ = ( + 'ControlServiceClient', + 'ControlServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/async_client.py new file mode 100644 index 00000000..23f62cb8 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/async_client.py @@ -0,0 +1,874 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.control_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import control +from google.cloud.retail_v2.types import control as gcr_control +from google.cloud.retail_v2.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .client import ControlServiceClient + + +class ControlServiceAsyncClient: + """Service for modifying Control.""" + + _client: ControlServiceClient + + DEFAULT_ENDPOINT = ControlServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ControlServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ControlServiceClient.catalog_path) + parse_catalog_path = staticmethod(ControlServiceClient.parse_catalog_path) + control_path = staticmethod(ControlServiceClient.control_path) + parse_control_path = staticmethod(ControlServiceClient.parse_control_path) + common_billing_account_path = staticmethod(ControlServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ControlServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ControlServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ControlServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ControlServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ControlServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ControlServiceClient.common_project_path) + parse_common_project_path = staticmethod(ControlServiceClient.parse_common_project_path) + common_location_path = staticmethod(ControlServiceClient.common_location_path) + parse_common_location_path = staticmethod(ControlServiceClient.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: + ControlServiceAsyncClient: The constructed client. + """ + return ControlServiceClient.from_service_account_info.__func__(ControlServiceAsyncClient, 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: + ControlServiceAsyncClient: The constructed client. + """ + return ControlServiceClient.from_service_account_file.__func__(ControlServiceAsyncClient, 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 ControlServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ControlServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ControlServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ControlServiceClient).get_transport_class, type(ControlServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ControlServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the control service 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, ~.ControlServiceTransport]): 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 = ControlServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_control(self, + request: Optional[Union[control_service.CreateControlRequest, dict]] = None, + *, + parent: Optional[str] = None, + control: Optional[gcr_control.Control] = None, + control_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_control.Control: + r"""Creates a Control. + + If the [Control][google.cloud.retail.v2.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2 + + async def sample_create_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = await client.create_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.CreateControlRequest, dict]]): + The request object. Request for CreateControl method. + parent (:class:`str`): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control (:class:`google.cloud.retail_v2.types.Control`): + Required. The Control to create. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control_id (:class:`str`): + Required. The ID to use for the Control, which will + become the final component of the Control's resource + name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``control_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.retail_v2.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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, control, control_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 = control_service.CreateControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if control is not None: + request.control = control + if control_id is not None: + request.control_id = control_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_control, + 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, + ) + + # Done; return the response. + return response + + async def delete_control(self, + request: Optional[Union[control_service.DeleteControlRequest, 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"""Deletes a Control. + + If the [Control][google.cloud.retail.v2.Control] to delete does + not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + async def sample_delete_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteControlRequest( + name="name_value", + ) + + # Make the request + await client.delete_control(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.DeleteControlRequest, dict]]): + The request object. Request for DeleteControl method. + name (:class:`str`): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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 = control_service.DeleteControlRequest(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_control, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_control(self, + request: Optional[Union[control_service.UpdateControlRequest, dict]] = None, + *, + control: Optional[gcr_control.Control] = 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]] = (), + ) -> gcr_control.Control: + r"""Updates a Control. + + [Control][google.cloud.retail.v2.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2.Control] to update does not + exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + async def sample_update_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateControlRequest( + control=control, + ) + + # Make the request + response = await client.update_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateControlRequest, dict]]): + The request object. Request for UpdateControl method. + control (:class:`google.cloud.retail_v2.types.Control`): + Required. The Control to update. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Control][google.cloud.retail.v2.Control] to update. The + following are NOT supported: + + - [Control.name][google.cloud.retail.v2.Control.name] + + If not set or empty, all supported fields are updated. + + 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.retail_v2.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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([control, 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 = control_service.UpdateControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if control is not None: + request.control = control + 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_control, + 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(( + ("control.name", request.control.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_control(self, + request: Optional[Union[control_service.GetControlRequest, 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]] = (), + ) -> control.Control: + r"""Gets a Control. + + .. 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 retail_v2 + + async def sample_get_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetControlRequest( + name="name_value", + ) + + # Make the request + response = await client.get_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.GetControlRequest, dict]]): + The request object. Request for GetControl method. + name (:class:`str`): + Required. The resource name of the Control to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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.retail_v2.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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 = control_service.GetControlRequest(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_control, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_controls(self, + request: Optional[Union[control_service.ListControlsRequest, 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.ListControlsAsyncPager: + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2.Catalog]. + + .. 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 retail_v2 + + async def sample_list_controls(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ListControlsRequest, dict]]): + The request object. Request for ListControls method. + parent (:class:`str`): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2.services.control_service.pagers.ListControlsAsyncPager: + Response for ListControls 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 = control_service.ListControlsRequest(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_controls, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListControlsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ControlServiceAsyncClient": + 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__ = ( + "ControlServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/client.py new file mode 100644 index 00000000..ad8f8591 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/client.py @@ -0,0 +1,1090 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.control_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import control +from google.cloud.retail_v2.types import control as gcr_control +from google.cloud.retail_v2.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ControlServiceGrpcTransport +from .transports.grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .transports.rest import ControlServiceRestTransport + + +class ControlServiceClientMeta(type): + """Metaclass for the ControlService 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[ControlServiceTransport]] + _transport_registry["grpc"] = ControlServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ControlServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ControlServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ControlServiceTransport]: + """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 ControlServiceClient(metaclass=ControlServiceClientMeta): + """Service for modifying Control.""" + + @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 = "retail.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: + ControlServiceClient: 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: + ControlServiceClient: 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) -> ControlServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ControlServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def control_path(project: str,location: str,catalog: str,control: str,) -> str: + """Returns a fully-qualified control string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/controls/{control}".format(project=project, location=location, catalog=catalog, control=control, ) + + @staticmethod + def parse_control_path(path: str) -> Dict[str,str]: + """Parses a control path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/controls/(?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, ControlServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the control service 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, ControlServiceTransport]): 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, ControlServiceTransport): + # transport is a ControlServiceTransport 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_control(self, + request: Optional[Union[control_service.CreateControlRequest, dict]] = None, + *, + parent: Optional[str] = None, + control: Optional[gcr_control.Control] = None, + control_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_control.Control: + r"""Creates a Control. + + If the [Control][google.cloud.retail.v2.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2 + + def sample_create_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = client.create_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.CreateControlRequest, dict]): + The request object. Request for CreateControl method. + parent (str): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control (google.cloud.retail_v2.types.Control): + Required. The Control to create. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control_id (str): + Required. The ID to use for the Control, which will + become the final component of the Control's resource + name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``control_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.retail_v2.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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, control, control_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 control_service.CreateControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.CreateControlRequest): + request = control_service.CreateControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if control is not None: + request.control = control + if control_id is not None: + request.control_id = control_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_control] + + # 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_control(self, + request: Optional[Union[control_service.DeleteControlRequest, 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"""Deletes a Control. + + If the [Control][google.cloud.retail.v2.Control] to delete does + not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + def sample_delete_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteControlRequest( + name="name_value", + ) + + # Make the request + client.delete_control(request=request) + + Args: + request (Union[google.cloud.retail_v2.types.DeleteControlRequest, dict]): + The request object. Request for DeleteControl method. + name (str): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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 control_service.DeleteControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.DeleteControlRequest): + request = control_service.DeleteControlRequest(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_control] + + # 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 update_control(self, + request: Optional[Union[control_service.UpdateControlRequest, dict]] = None, + *, + control: Optional[gcr_control.Control] = 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]] = (), + ) -> gcr_control.Control: + r"""Updates a Control. + + [Control][google.cloud.retail.v2.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2.Control] to update does not + exist, a NOT_FOUND error is returned. + + .. 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 retail_v2 + + def sample_update_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateControlRequest( + control=control, + ) + + # Make the request + response = client.update_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateControlRequest, dict]): + The request object. Request for UpdateControl method. + control (google.cloud.retail_v2.types.Control): + Required. The Control to update. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Control][google.cloud.retail.v2.Control] to update. The + following are NOT supported: + + - [Control.name][google.cloud.retail.v2.Control.name] + + If not set or empty, all supported fields are updated. + + 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.retail_v2.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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([control, 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 control_service.UpdateControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.UpdateControlRequest): + request = control_service.UpdateControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if control is not None: + request.control = control + 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_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("control.name", request.control.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_control(self, + request: Optional[Union[control_service.GetControlRequest, 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]] = (), + ) -> control.Control: + r"""Gets a Control. + + .. 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 retail_v2 + + def sample_get_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetControlRequest( + name="name_value", + ) + + # Make the request + response = client.get_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetControlRequest, dict]): + The request object. Request for GetControl method. + name (str): + Required. The resource name of the Control to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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.retail_v2.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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 control_service.GetControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.GetControlRequest): + request = control_service.GetControlRequest(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_control] + + # 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 list_controls(self, + request: Optional[Union[control_service.ListControlsRequest, 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.ListControlsPager: + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2.Catalog]. + + .. 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 retail_v2 + + def sample_list_controls(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ListControlsRequest, dict]): + The request object. Request for ListControls method. + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2.services.control_service.pagers.ListControlsPager: + Response for ListControls 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 control_service.ListControlsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.ListControlsRequest): + request = control_service.ListControlsRequest(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_controls] + + # 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.ListControlsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ControlServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ControlServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/pagers.py new file mode 100644 index 00000000..5d96b72b --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import control +from google.cloud.retail_v2.types import control_service + + +class ListControlsPager: + """A pager for iterating through ``list_controls`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListControlsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``controls`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListControls`` requests and continue to iterate + through the ``controls`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListControlsResponse` + 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[..., control_service.ListControlsResponse], + request: control_service.ListControlsRequest, + response: control_service.ListControlsResponse, + *, + 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.retail_v2.types.ListControlsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListControlsResponse): + 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 = control_service.ListControlsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[control_service.ListControlsResponse]: + 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[control.Control]: + for page in self.pages: + yield from page.controls + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListControlsAsyncPager: + """A pager for iterating through ``list_controls`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListControlsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``controls`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListControls`` requests and continue to iterate + through the ``controls`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListControlsResponse` + 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[control_service.ListControlsResponse]], + request: control_service.ListControlsRequest, + response: control_service.ListControlsResponse, + *, + 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.retail_v2.types.ListControlsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListControlsResponse): + 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 = control_service.ListControlsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[control_service.ListControlsResponse]: + 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[control.Control]: + async def async_generator(): + async for page in self.pages: + for response in page.controls: + 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/v2/google/cloud/retail_v2/services/control_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/__init__.py new file mode 100644 index 00000000..103fc931 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/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 ControlServiceTransport +from .grpc import ControlServiceGrpcTransport +from .grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .rest import ControlServiceRestTransport +from .rest import ControlServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ControlServiceTransport]] +_transport_registry['grpc'] = ControlServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ControlServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ControlServiceRestTransport + +__all__ = ( + 'ControlServiceTransport', + 'ControlServiceGrpcTransport', + 'ControlServiceGrpcAsyncIOTransport', + 'ControlServiceRestTransport', + 'ControlServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/base.py new file mode 100644 index 00000000..b85181c7 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/base.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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import control +from google.cloud.retail_v2.types import control as gcr_control +from google.cloud.retail_v2.types import control_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 ControlServiceTransport(abc.ABC): + """Abstract transport class for ControlService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_control: gapic_v1.method.wrap_method( + self.create_control, + default_timeout=None, + client_info=client_info, + ), + self.delete_control: gapic_v1.method.wrap_method( + self.delete_control, + default_timeout=None, + client_info=client_info, + ), + self.update_control: gapic_v1.method.wrap_method( + self.update_control, + default_timeout=None, + client_info=client_info, + ), + self.get_control: gapic_v1.method.wrap_method( + self.get_control, + default_timeout=None, + client_info=client_info, + ), + self.list_controls: gapic_v1.method.wrap_method( + self.list_controls, + 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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + Union[ + gcr_control.Control, + Awaitable[gcr_control.Control] + ]]: + raise NotImplementedError() + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + Union[ + gcr_control.Control, + Awaitable[gcr_control.Control] + ]]: + raise NotImplementedError() + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + Union[ + control.Control, + Awaitable[control.Control] + ]]: + raise NotImplementedError() + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + Union[ + control_service.ListControlsResponse, + Awaitable[control_service.ListControlsResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ControlServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc.py new file mode 100644 index 00000000..0b092c82 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import control +from google.cloud.retail_v2.types import control as gcr_control +from google.cloud.retail_v2.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ControlServiceTransport, DEFAULT_CLIENT_INFO + + +class ControlServiceGrpcTransport(ControlServiceTransport): + """gRPC backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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 = 'retail.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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + gcr_control.Control]: + r"""Return a callable for the create control method over gRPC. + + Creates a Control. + + If the [Control][google.cloud.retail.v2.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.CreateControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['create_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/CreateControl', + request_serializer=control_service.CreateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['create_control'] + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete control method over gRPC. + + Deletes a Control. + + If the [Control][google.cloud.retail.v2.Control] to delete does + not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteControlRequest], + ~.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_control' not in self._stubs: + self._stubs['delete_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/DeleteControl', + request_serializer=control_service.DeleteControlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_control'] + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + gcr_control.Control]: + r"""Return a callable for the update control method over gRPC. + + Updates a Control. + + [Control][google.cloud.retail.v2.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2.Control] to update does not + exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.UpdateControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['update_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/UpdateControl', + request_serializer=control_service.UpdateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['update_control'] + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + control.Control]: + r"""Return a callable for the get control method over gRPC. + + Gets a Control. + + Returns: + Callable[[~.GetControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['get_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/GetControl', + request_serializer=control_service.GetControlRequest.serialize, + response_deserializer=control.Control.deserialize, + ) + return self._stubs['get_control'] + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + control_service.ListControlsResponse]: + r"""Return a callable for the list controls method over gRPC. + + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2.Catalog]. + + Returns: + Callable[[~.ListControlsRequest], + ~.ListControlsResponse]: + 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_controls' not in self._stubs: + self._stubs['list_controls'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/ListControls', + request_serializer=control_service.ListControlsRequest.serialize, + response_deserializer=control_service.ListControlsResponse.deserialize, + ) + return self._stubs['list_controls'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ControlServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..0ba0c8c1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/grpc_asyncio.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import control +from google.cloud.retail_v2.types import control as gcr_control +from google.cloud.retail_v2.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ControlServiceGrpcTransport + + +class ControlServiceGrpcAsyncIOTransport(ControlServiceTransport): + """gRPC AsyncIO backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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 = 'retail.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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + Awaitable[gcr_control.Control]]: + r"""Return a callable for the create control method over gRPC. + + Creates a Control. + + If the [Control][google.cloud.retail.v2.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.CreateControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['create_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/CreateControl', + request_serializer=control_service.CreateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['create_control'] + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete control method over gRPC. + + Deletes a Control. + + If the [Control][google.cloud.retail.v2.Control] to delete does + not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteControlRequest], + 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_control' not in self._stubs: + self._stubs['delete_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/DeleteControl', + request_serializer=control_service.DeleteControlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_control'] + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + Awaitable[gcr_control.Control]]: + r"""Return a callable for the update control method over gRPC. + + Updates a Control. + + [Control][google.cloud.retail.v2.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2.Control] to update does not + exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.UpdateControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['update_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/UpdateControl', + request_serializer=control_service.UpdateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['update_control'] + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + Awaitable[control.Control]]: + r"""Return a callable for the get control method over gRPC. + + Gets a Control. + + Returns: + Callable[[~.GetControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['get_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/GetControl', + request_serializer=control_service.GetControlRequest.serialize, + response_deserializer=control.Control.deserialize, + ) + return self._stubs['get_control'] + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + Awaitable[control_service.ListControlsResponse]]: + r"""Return a callable for the list controls method over gRPC. + + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2.Catalog]. + + Returns: + Callable[[~.ListControlsRequest], + Awaitable[~.ListControlsResponse]]: + 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_controls' not in self._stubs: + self._stubs['list_controls'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ControlService/ListControls', + request_serializer=control_service.ListControlsRequest.serialize, + response_deserializer=control_service.ListControlsResponse.deserialize, + ) + return self._stubs['list_controls'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ControlServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/rest.py new file mode 100644 index 00000000..b00bd5b0 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/control_service/transports/rest.py @@ -0,0 +1,930 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import control +from google.cloud.retail_v2.types import control as gcr_control +from google.cloud.retail_v2.types import control_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ControlServiceTransport, 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 ControlServiceRestInterceptor: + """Interceptor for ControlService. + + 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 ControlServiceRestTransport. + + .. code-block:: python + class MyCustomControlServiceInterceptor(ControlServiceRestInterceptor): + def pre_create_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_controls(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_controls(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_control(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ControlServiceRestTransport(interceptor=MyCustomControlServiceInterceptor()) + client = ControlServiceClient(transport=transport) + + + """ + def pre_create_control(self, request: control_service.CreateControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.CreateControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_create_control(self, response: gcr_control.Control) -> gcr_control.Control: + """Post-rpc interceptor for create_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_delete_control(self, request: control_service.DeleteControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.DeleteControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def pre_get_control(self, request: control_service.GetControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.GetControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_get_control(self, response: control.Control) -> control.Control: + """Post-rpc interceptor for get_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_list_controls(self, request: control_service.ListControlsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.ListControlsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_controls + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_list_controls(self, response: control_service.ListControlsResponse) -> control_service.ListControlsResponse: + """Post-rpc interceptor for list_controls + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_update_control(self, request: control_service.UpdateControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.UpdateControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_update_control(self, response: gcr_control.Control) -> gcr_control.Control: + """Post-rpc interceptor for update_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ControlServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ControlServiceRestInterceptor + + +class ControlServiceRestTransport(ControlServiceTransport): + """REST backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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[ControlServiceRestInterceptor] = 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 ControlServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _CreateControl(ControlServiceRestStub): + def __hash__(self): + return hash("CreateControl") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "controlId" : "", } + + @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: control_service.CreateControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_control.Control: + r"""Call the create control method over HTTP. + + Args: + request (~.control_service.CreateControlRequest): + The request object. Request for CreateControl 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: + ~.gcr_control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*}/controls', + 'body': 'control', + }, + ] + request, metadata = self._interceptor.pre_create_control(request, metadata) + pb_request = control_service.CreateControlRequest.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 = gcr_control.Control() + pb_resp = gcr_control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_control(resp) + return resp + + class _DeleteControl(ControlServiceRestStub): + def __hash__(self): + return hash("DeleteControl") + + __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: control_service.DeleteControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete control method over HTTP. + + Args: + request (~.control_service.DeleteControlRequest): + The request object. Request for DeleteControl 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': '/v2/{name=projects/*/locations/*/catalogs/*/controls/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_control(request, metadata) + pb_request = control_service.DeleteControlRequest.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 _GetControl(ControlServiceRestStub): + def __hash__(self): + return hash("GetControl") + + __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: control_service.GetControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> control.Control: + r"""Call the get control method over HTTP. + + Args: + request (~.control_service.GetControlRequest): + The request object. Request for GetControl 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: + ~.control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/controls/*}', + }, + ] + request, metadata = self._interceptor.pre_get_control(request, metadata) + pb_request = control_service.GetControlRequest.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 = control.Control() + pb_resp = control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_control(resp) + return resp + + class _ListControls(ControlServiceRestStub): + def __hash__(self): + return hash("ListControls") + + __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: control_service.ListControlsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> control_service.ListControlsResponse: + r"""Call the list controls method over HTTP. + + Args: + request (~.control_service.ListControlsRequest): + The request object. Request for ListControls 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: + ~.control_service.ListControlsResponse: + Response for ListControls method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*}/controls', + }, + ] + request, metadata = self._interceptor.pre_list_controls(request, metadata) + pb_request = control_service.ListControlsRequest.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 = control_service.ListControlsResponse() + pb_resp = control_service.ListControlsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_controls(resp) + return resp + + class _UpdateControl(ControlServiceRestStub): + def __hash__(self): + return hash("UpdateControl") + + __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: control_service.UpdateControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_control.Control: + r"""Call the update control method over HTTP. + + Args: + request (~.control_service.UpdateControlRequest): + The request object. Request for UpdateControl 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: + ~.gcr_control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2/{control.name=projects/*/locations/*/catalogs/*/controls/*}', + 'body': 'control', + }, + ] + request, metadata = self._interceptor.pre_update_control(request, metadata) + pb_request = control_service.UpdateControlRequest.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 = gcr_control.Control() + pb_resp = gcr_control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_control(resp) + return resp + + @property + def create_control(self) -> Callable[ + [control_service.CreateControlRequest], + gcr_control.Control]: + # 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._CreateControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + 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._DeleteControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + control.Control]: + # 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._GetControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + control_service.ListControlsResponse]: + # 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._ListControls(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + gcr_control.Control]: + # 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._UpdateControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ControlServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ControlServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ControlServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/__init__.py new file mode 100644 index 00000000..2c368b92 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/__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 ModelServiceClient +from .async_client import ModelServiceAsyncClient + +__all__ = ( + 'ModelServiceClient', + 'ModelServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/async_client.py new file mode 100644 index 00000000..c6a8f993 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/async_client.py @@ -0,0 +1,1218 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.model_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .client import ModelServiceClient + + +class ModelServiceAsyncClient: + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + _client: ModelServiceClient + + DEFAULT_ENDPOINT = ModelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ModelServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ModelServiceClient.catalog_path) + parse_catalog_path = staticmethod(ModelServiceClient.parse_catalog_path) + model_path = staticmethod(ModelServiceClient.model_path) + parse_model_path = staticmethod(ModelServiceClient.parse_model_path) + common_billing_account_path = staticmethod(ModelServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ModelServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ModelServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ModelServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ModelServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ModelServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ModelServiceClient.common_project_path) + parse_common_project_path = staticmethod(ModelServiceClient.parse_common_project_path) + common_location_path = staticmethod(ModelServiceClient.common_location_path) + parse_common_location_path = staticmethod(ModelServiceClient.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: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_info.__func__(ModelServiceAsyncClient, 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: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_file.__func__(ModelServiceAsyncClient, 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 ModelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ModelServiceClient).get_transport_class, type(ModelServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ModelServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service 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, ~.ModelServiceTransport]): 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 = ModelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_model(self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new model. + + .. 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 retail_v2 + + async def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.CreateModelRequest, dict]]): + The request object. Request for creating a model. + parent (:class:`str`): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (:class:`google.cloud.retail_v2.types.Model`): + Required. The payload of the + [Model][google.cloud.retail.v2.Model] to create. + + This corresponds to the ``model`` 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.retail_v2.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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, model]) + 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 = model_service.CreateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # 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_model, + 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, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + async def get_model(self, + request: Optional[Union[model_service.GetModelRequest, 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]] = (), + ) -> model.Model: + r"""Gets a model. + + .. 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 retail_v2 + + async def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.GetModelRequest, dict]]): + The request object. Request for getting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.GetModelRequest(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_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def pause_model(self, + request: Optional[Union[model_service.PauseModelRequest, 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]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. 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 retail_v2 + + async def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.PauseModelRequest, dict]]): + The request object. Request for pausing training of a + model. + name (:class:`str`): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.PauseModelRequest(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.pause_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def resume_model(self, + request: Optional[Union[model_service.ResumeModelRequest, 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]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. 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 retail_v2 + + async def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ResumeModelRequest, dict]]): + The request object. Request for resuming training of a + model. + name (:class:`str`): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.ResumeModelRequest(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.resume_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_model(self, + request: Optional[Union[model_service.DeleteModelRequest, 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"""Deletes an existing model. + + .. 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 retail_v2 + + async def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.DeleteModelRequest, dict]]): + The request object. Request for deleting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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 = model_service.DeleteModelRequest(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_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_models(self, + request: Optional[Union[model_service.ListModelsRequest, 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.ListModelsAsyncPager: + r"""Lists all the models linked to this event store. + + .. 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 retail_v2 + + async def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ListModelsRequest, dict]]): + The request object. Request for listing models associated + with a resource. + parent (:class:`str`): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2.services.model_service.pagers.ListModelsAsyncPager: + Response to a ListModelRequest. + + 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 = model_service.ListModelsRequest(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_models, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListModelsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_model(self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = 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]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. 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 retail_v2 + + async def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateModelRequest, dict]]): + The request object. Request for updating an existing + model. + model (:class:`google.cloud.retail_v2.types.Model`): + Required. The body of the updated + [Model][google.cloud.retail.v2.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + 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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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([model, 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 = model_service.UpdateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + 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_model, + 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(( + ("model.name", request.model.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def tune_model(self, + request: Optional[Union[model_service.TuneModelRequest, 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]] = (), + ) -> operation_async.AsyncOperation: + r"""Tunes an existing model. + + .. 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 retail_v2 + + async def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.TuneModelRequest, dict]]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (:class:`str`): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # 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 = model_service.TuneModelRequest(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.tune_model, + 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(( + ("name", request.name), + )), + ) + + # 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, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ModelServiceAsyncClient": + 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__ = ( + "ModelServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/client.py new file mode 100644 index 00000000..0b724edc --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/client.py @@ -0,0 +1,1434 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.model_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ModelServiceGrpcTransport +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .transports.rest import ModelServiceRestTransport + + +class ModelServiceClientMeta(type): + """Metaclass for the ModelService 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[ModelServiceTransport]] + _transport_registry["grpc"] = ModelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ModelServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ModelServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ModelServiceTransport]: + """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 ModelServiceClient(metaclass=ModelServiceClientMeta): + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + @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 = "retail.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: + ModelServiceClient: 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: + ModelServiceClient: 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) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def model_path(project: str,location: str,catalog: str,model: str,) -> str: + """Returns a fully-qualified model string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format(project=project, location=location, catalog=catalog, model=model, ) + + @staticmethod + def parse_model_path(path: str) -> Dict[str,str]: + """Parses a model path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/models/(?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, ModelServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service 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, ModelServiceTransport]): 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, ModelServiceTransport): + # transport is a ModelServiceTransport 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_model(self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a new model. + + .. 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 retail_v2 + + def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.CreateModelRequest, dict]): + The request object. Request for creating a model. + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (google.cloud.retail_v2.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2.Model] to create. + + This corresponds to the ``model`` 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.retail_v2.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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, model]) + 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 model_service.CreateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.CreateModelRequest): + request = model_service.CreateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_model] + + # 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, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + def get_model(self, + request: Optional[Union[model_service.GetModelRequest, 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]] = (), + ) -> model.Model: + r"""Gets a model. + + .. 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 retail_v2 + + def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetModelRequest, dict]): + The request object. Request for getting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.GetModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.GetModelRequest): + request = model_service.GetModelRequest(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_model] + + # 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 pause_model(self, + request: Optional[Union[model_service.PauseModelRequest, 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]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. 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 retail_v2 + + def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.PauseModelRequest, dict]): + The request object. Request for pausing training of a + model. + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.PauseModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.PauseModelRequest): + request = model_service.PauseModelRequest(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.pause_model] + + # 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 resume_model(self, + request: Optional[Union[model_service.ResumeModelRequest, 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]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. 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 retail_v2 + + def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ResumeModelRequest, dict]): + The request object. Request for resuming training of a + model. + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.ResumeModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ResumeModelRequest): + request = model_service.ResumeModelRequest(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.resume_model] + + # 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 delete_model(self, + request: Optional[Union[model_service.DeleteModelRequest, 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"""Deletes an existing model. + + .. 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 retail_v2 + + def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + Args: + request (Union[google.cloud.retail_v2.types.DeleteModelRequest, dict]): + The request object. Request for deleting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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 model_service.DeleteModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.DeleteModelRequest): + request = model_service.DeleteModelRequest(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_model] + + # 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_models(self, + request: Optional[Union[model_service.ListModelsRequest, 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.ListModelsPager: + r"""Lists all the models linked to this event store. + + .. 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 retail_v2 + + def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ListModelsRequest, dict]): + The request object. Request for listing models associated + with a resource. + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2.services.model_service.pagers.ListModelsPager: + Response to a ListModelRequest. + + 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 model_service.ListModelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ListModelsRequest): + request = model_service.ListModelsRequest(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_models] + + # 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.ListModelsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_model(self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = 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]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. 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 retail_v2 + + def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateModelRequest, dict]): + The request object. Request for updating an existing + model. + model (google.cloud.retail_v2.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + 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.retail_v2.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + # 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([model, 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 model_service.UpdateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.UpdateModelRequest): + request = model_service.UpdateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + 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_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("model.name", request.model.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def tune_model(self, + request: Optional[Union[model_service.TuneModelRequest, 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]] = (), + ) -> operation.Operation: + r"""Tunes an existing model. + + .. 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 retail_v2 + + def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.TuneModelRequest, dict]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (str): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # 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 model_service.TuneModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.TuneModelRequest): + request = model_service.TuneModelRequest(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.tune_model] + + # 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, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ModelServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ModelServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/pagers.py new file mode 100644 index 00000000..11518112 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import model +from google.cloud.retail_v2.types import model_service + + +class ListModelsPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListModelsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListModelsResponse` + 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[..., model_service.ListModelsResponse], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + 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.retail_v2.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListModelsResponse): + 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 = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[model_service.ListModelsResponse]: + 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[model.Model]: + for page in self.pages: + yield from page.models + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListModelsAsyncPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListModelsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListModelsResponse` + 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[model_service.ListModelsResponse]], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + 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.retail_v2.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListModelsResponse): + 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 = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[model_service.ListModelsResponse]: + 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[model.Model]: + async def async_generator(): + async for page in self.pages: + for response in page.models: + 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/v2/google/cloud/retail_v2/services/model_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/__init__.py new file mode 100644 index 00000000..c51cadf4 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/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 ModelServiceTransport +from .grpc import ModelServiceGrpcTransport +from .grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .rest import ModelServiceRestTransport +from .rest import ModelServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ModelServiceTransport]] +_transport_registry['grpc'] = ModelServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ModelServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ModelServiceRestTransport + +__all__ = ( + 'ModelServiceTransport', + 'ModelServiceGrpcTransport', + 'ModelServiceGrpcAsyncIOTransport', + 'ModelServiceRestTransport', + 'ModelServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/base.py new file mode 100644 index 00000000..eb0a3b65 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/base.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_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 ModelServiceTransport(abc.ABC): + """Abstract transport class for ModelService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_model: gapic_v1.method.wrap_method( + self.create_model, + default_timeout=None, + client_info=client_info, + ), + self.get_model: gapic_v1.method.wrap_method( + self.get_model, + default_timeout=None, + client_info=client_info, + ), + self.pause_model: gapic_v1.method.wrap_method( + self.pause_model, + default_timeout=None, + client_info=client_info, + ), + self.resume_model: gapic_v1.method.wrap_method( + self.resume_model, + default_timeout=None, + client_info=client_info, + ), + self.delete_model: gapic_v1.method.wrap_method( + self.delete_model, + default_timeout=None, + client_info=client_info, + ), + self.list_models: gapic_v1.method.wrap_method( + self.list_models, + default_timeout=None, + client_info=client_info, + ), + self.update_model: gapic_v1.method.wrap_method( + self.update_model, + default_timeout=None, + client_info=client_info, + ), + self.tune_model: gapic_v1.method.wrap_method( + self.tune_model, + 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_model(self) -> Callable[ + [model_service.CreateModelRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + Union[ + model_service.ListModelsResponse, + Awaitable[model_service.ListModelsResponse] + ]]: + raise NotImplementedError() + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + Union[ + gcr_model.Model, + Awaitable[gcr_model.Model] + ]]: + raise NotImplementedError() + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ModelServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc.py new file mode 100644 index 00000000..7dc9bbf1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc.py @@ -0,0 +1,518 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ModelServiceTransport, DEFAULT_CLIENT_INFO + + +class ModelServiceGrpcTransport(ModelServiceTransport): + """gRPC backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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 = 'retail.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_model(self) -> Callable[ + [model_service.CreateModelRequest], + operations_pb2.Operation]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + ~.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 'create_model' not in self._stubs: + self._stubs['create_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/CreateModel', + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_model'] + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + model.Model]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + ~.Model]: + 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_model' not in self._stubs: + self._stubs['get_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/GetModel', + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['get_model'] + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + model.Model]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + ~.Model]: + 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 'pause_model' not in self._stubs: + self._stubs['pause_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/PauseModel', + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['pause_model'] + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + model.Model]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + ~.Model]: + 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 'resume_model' not in self._stubs: + self._stubs['resume_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/ResumeModel', + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['resume_model'] + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + ~.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_model' not in self._stubs: + self._stubs['delete_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/DeleteModel', + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_model'] + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + model_service.ListModelsResponse]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + ~.ListModelsResponse]: + 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_models' not in self._stubs: + self._stubs['list_models'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/ListModels', + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs['list_models'] + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + gcr_model.Model]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + ~.Model]: + 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_model' not in self._stubs: + self._stubs['update_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/UpdateModel', + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs['update_model'] + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + operations_pb2.Operation]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + ~.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 'tune_model' not in self._stubs: + self._stubs['tune_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/TuneModel', + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['tune_model'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ModelServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..cf9285cf --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/grpc_asyncio.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ModelServiceGrpcTransport + + +class ModelServiceGrpcAsyncIOTransport(ModelServiceTransport): + """gRPC AsyncIO backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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 = 'retail.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_model(self) -> Callable[ + [model_service.CreateModelRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + 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 'create_model' not in self._stubs: + self._stubs['create_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/CreateModel', + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_model'] + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + Awaitable[~.Model]]: + 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_model' not in self._stubs: + self._stubs['get_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/GetModel', + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['get_model'] + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + Awaitable[~.Model]]: + 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 'pause_model' not in self._stubs: + self._stubs['pause_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/PauseModel', + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['pause_model'] + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + Awaitable[~.Model]]: + 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 'resume_model' not in self._stubs: + self._stubs['resume_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/ResumeModel', + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['resume_model'] + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + 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_model' not in self._stubs: + self._stubs['delete_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/DeleteModel', + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_model'] + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + Awaitable[model_service.ListModelsResponse]]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + Awaitable[~.ListModelsResponse]]: + 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_models' not in self._stubs: + self._stubs['list_models'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/ListModels', + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs['list_models'] + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + Awaitable[gcr_model.Model]]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + Awaitable[~.Model]]: + 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_model' not in self._stubs: + self._stubs['update_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/UpdateModel', + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs['update_model'] + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + 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 'tune_model' not in self._stubs: + self._stubs['tune_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ModelService/TuneModel', + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['tune_model'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ModelServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/rest.py new file mode 100644 index 00000000..4435ac89 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/model_service/transports/rest.py @@ -0,0 +1,1378 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ModelServiceTransport, 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 ModelServiceRestInterceptor: + """Interceptor for ModelService. + + 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 ModelServiceRestTransport. + + .. code-block:: python + class MyCustomModelServiceInterceptor(ModelServiceRestInterceptor): + def pre_create_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_models(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_models(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_pause_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_pause_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_resume_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_resume_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_tune_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_tune_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_model(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ModelServiceRestTransport(interceptor=MyCustomModelServiceInterceptor()) + client = ModelServiceClient(transport=transport) + + + """ + def pre_create_model(self, request: model_service.CreateModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.CreateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_create_model(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for create_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_delete_model(self, request: model_service.DeleteModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.DeleteModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def pre_get_model(self, request: model_service.GetModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.GetModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for get_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_models(self, request: model_service.ListModelsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.ListModelsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_models + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_models(self, response: model_service.ListModelsResponse) -> model_service.ListModelsResponse: + """Post-rpc interceptor for list_models + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_pause_model(self, request: model_service.PauseModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.PauseModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for pause_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_pause_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for pause_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_resume_model(self, request: model_service.ResumeModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.ResumeModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for resume_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_resume_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for resume_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_tune_model(self, request: model_service.TuneModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.TuneModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for tune_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_tune_model(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for tune_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_update_model(self, request: model_service.UpdateModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.UpdateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_update_model(self, response: gcr_model.Model) -> gcr_model.Model: + """Post-rpc interceptor for update_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ModelServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ModelServiceRestInterceptor + + +class ModelServiceRestTransport(ModelServiceTransport): + """REST backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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[ModelServiceRestInterceptor] = 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 ModelServiceRestInterceptor() + 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': '/v2/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*}/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="v2") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CreateModel(ModelServiceRestStub): + def __hash__(self): + return hash("CreateModel") + + __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: model_service.CreateModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the create model method over HTTP. + + Args: + request (~.model_service.CreateModelRequest): + The request object. Request for creating a model. + 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': '/v2/{parent=projects/*/locations/*/catalogs/*}/models', + 'body': 'model', + }, + ] + request, metadata = self._interceptor.pre_create_model(request, metadata) + pb_request = model_service.CreateModelRequest.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_create_model(resp) + return resp + + class _DeleteModel(ModelServiceRestStub): + def __hash__(self): + return hash("DeleteModel") + + __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: model_service.DeleteModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete model method over HTTP. + + Args: + request (~.model_service.DeleteModelRequest): + The request object. Request for deleting a model. + 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': '/v2/{name=projects/*/locations/*/catalogs/*/models/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_model(request, metadata) + pb_request = model_service.DeleteModelRequest.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 _GetModel(ModelServiceRestStub): + def __hash__(self): + return hash("GetModel") + + __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: model_service.GetModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the get model method over HTTP. + + Args: + request (~.model_service.GetModelRequest): + The request object. Request for getting a model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/models/*}', + }, + ] + request, metadata = self._interceptor.pre_get_model(request, metadata) + pb_request = model_service.GetModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_model(resp) + return resp + + class _ListModels(ModelServiceRestStub): + def __hash__(self): + return hash("ListModels") + + __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: model_service.ListModelsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model_service.ListModelsResponse: + r"""Call the list models method over HTTP. + + Args: + request (~.model_service.ListModelsRequest): + The request object. Request for listing models associated + with a resource. + 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: + ~.model_service.ListModelsResponse: + Response to a ListModelRequest. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*}/models', + }, + ] + request, metadata = self._interceptor.pre_list_models(request, metadata) + pb_request = model_service.ListModelsRequest.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 = model_service.ListModelsResponse() + pb_resp = model_service.ListModelsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_models(resp) + return resp + + class _PauseModel(ModelServiceRestStub): + def __hash__(self): + return hash("PauseModel") + + __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: model_service.PauseModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the pause model method over HTTP. + + Args: + request (~.model_service.PauseModelRequest): + The request object. Request for pausing training of a + model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/models/*}:pause', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_pause_model(request, metadata) + pb_request = model_service.PauseModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_pause_model(resp) + return resp + + class _ResumeModel(ModelServiceRestStub): + def __hash__(self): + return hash("ResumeModel") + + __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: model_service.ResumeModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the resume model method over HTTP. + + Args: + request (~.model_service.ResumeModelRequest): + The request object. Request for resuming training of a + model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/models/*}:resume', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_resume_model(request, metadata) + pb_request = model_service.ResumeModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_resume_model(resp) + return resp + + class _TuneModel(ModelServiceRestStub): + def __hash__(self): + return hash("TuneModel") + + __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: model_service.TuneModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the tune model method over HTTP. + + Args: + request (~.model_service.TuneModelRequest): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + 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': '/v2/{name=projects/*/locations/*/catalogs/*/models/*}:tune', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_tune_model(request, metadata) + pb_request = model_service.TuneModelRequest.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_tune_model(resp) + return resp + + class _UpdateModel(ModelServiceRestStub): + def __hash__(self): + return hash("UpdateModel") + + __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: model_service.UpdateModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_model.Model: + r"""Call the update model method over HTTP. + + Args: + request (~.model_service.UpdateModelRequest): + The request object. Request for updating an existing + model. + 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: + ~.gcr_model.Model: + Metadata that describes the training and serving + parameters of a [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated + with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2/{model.name=projects/*/locations/*/catalogs/*/models/*}', + 'body': 'model', + }, + ] + request, metadata = self._interceptor.pre_update_model(request, metadata) + pb_request = model_service.UpdateModelRequest.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 = gcr_model.Model() + pb_resp = gcr_model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_model(resp) + return resp + + @property + def create_model(self) -> Callable[ + [model_service.CreateModelRequest], + 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._CreateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + 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._DeleteModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + model.Model]: + # 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._GetModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + model_service.ListModelsResponse]: + # 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._ListModels(self._session, self._host, self._interceptor) # type: ignore + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + model.Model]: + # 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._PauseModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + model.Model]: + # 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._ResumeModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + 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._TuneModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + gcr_model.Model]: + # 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._UpdateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ModelServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ModelServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ModelServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__init__.py new file mode 100644 index 00000000..905b8c43 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/__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 PredictionServiceClient +from .async_client import PredictionServiceAsyncClient + +__all__ = ( + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py new file mode 100644 index 00000000..2bb18540 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/async_client.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .client import PredictionServiceClient + + +class PredictionServiceAsyncClient: + """Service for making recommendation prediction.""" + + _client: PredictionServiceClient + + DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(PredictionServiceClient.product_path) + parse_product_path = staticmethod(PredictionServiceClient.parse_product_path) + common_billing_account_path = staticmethod(PredictionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(PredictionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(PredictionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(PredictionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(PredictionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(PredictionServiceClient.common_project_path) + parse_common_project_path = staticmethod(PredictionServiceClient.parse_common_project_path) + common_location_path = staticmethod(PredictionServiceClient.common_location_path) + parse_common_location_path = staticmethod(PredictionServiceClient.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: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_info.__func__(PredictionServiceAsyncClient, 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: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_file.__func__(PredictionServiceAsyncClient, 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 PredictionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service 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, ~.PredictionServiceTransport]): 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 = PredictionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def predict(self, + request: Optional[Union[prediction_service.PredictRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + .. 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 retail_v2 + + async def sample_predict(): + # Create a client + client = retail_v2.PredictionServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = await client.predict(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.PredictRequest, dict]]): + The request object. Request message for Predict 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: + google.cloud.retail_v2.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.predict, + 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(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "PredictionServiceAsyncClient": + 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__ = ( + "PredictionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py new file mode 100644 index 00000000..c33b017a --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/client.py @@ -0,0 +1,592 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import PredictionServiceGrpcTransport +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .transports.rest import PredictionServiceRestTransport + + +class PredictionServiceClientMeta(type): + """Metaclass for the PredictionService 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[PredictionServiceTransport]] + _transport_registry["grpc"] = PredictionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = PredictionServiceGrpcAsyncIOTransport + _transport_registry["rest"] = PredictionServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[PredictionServiceTransport]: + """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 PredictionServiceClient(metaclass=PredictionServiceClientMeta): + """Service for making recommendation prediction.""" + + @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 = "retail.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: + PredictionServiceClient: 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: + PredictionServiceClient: 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) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, PredictionServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service 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, PredictionServiceTransport]): 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, PredictionServiceTransport): + # transport is a PredictionServiceTransport 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 predict(self, + request: Optional[Union[prediction_service.PredictRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + .. 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 retail_v2 + + def sample_predict(): + # Create a client + client = retail_v2.PredictionServiceClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = client.predict(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.PredictRequest, dict]): + The request object. Request message for Predict 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: + google.cloud.retail_v2.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a prediction_service.PredictRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, prediction_service.PredictRequest): + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.predict] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "PredictionServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "PredictionServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/__init__.py new file mode 100644 index 00000000..d8c81688 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/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 PredictionServiceTransport +from .grpc import PredictionServiceGrpcTransport +from .grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .rest import PredictionServiceRestTransport +from .rest import PredictionServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[PredictionServiceTransport]] +_transport_registry['grpc'] = PredictionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = PredictionServiceGrpcAsyncIOTransport +_transport_registry['rest'] = PredictionServiceRestTransport + +__all__ = ( + 'PredictionServiceTransport', + 'PredictionServiceGrpcTransport', + 'PredictionServiceGrpcAsyncIOTransport', + 'PredictionServiceRestTransport', + 'PredictionServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py new file mode 100644 index 00000000..88c65578 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/base.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class PredictionServiceTransport(abc.ABC): + """Abstract transport class for PredictionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.predict: gapic_v1.method.wrap_method( + self.predict, + 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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + Union[ + prediction_service.PredictResponse, + Awaitable[prediction_service.PredictResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'PredictionServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py new file mode 100644 index 00000000..8184e8f1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc.py @@ -0,0 +1,302 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO + + +class PredictionServiceGrpcTransport(PredictionServiceTransport): + """gRPC backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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 = 'retail.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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + prediction_service.PredictResponse]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + ~.PredictResponse]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'PredictionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..2c556dde --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/grpc_asyncio.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import PredictionServiceGrpcTransport + + +class PredictionServiceGrpcAsyncIOTransport(PredictionServiceTransport): + """gRPC AsyncIO backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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 = 'retail.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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + Awaitable[prediction_service.PredictResponse]]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + Awaitable[~.PredictResponse]]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'PredictionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/rest.py new file mode 100644 index 00000000..cb61248b --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/prediction_service/transports/rest.py @@ -0,0 +1,495 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import PredictionServiceTransport, 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 PredictionServiceRestInterceptor: + """Interceptor for PredictionService. + + 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 PredictionServiceRestTransport. + + .. code-block:: python + class MyCustomPredictionServiceInterceptor(PredictionServiceRestInterceptor): + def pre_predict(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_predict(self, response): + logging.log(f"Received response: {response}") + return response + + transport = PredictionServiceRestTransport(interceptor=MyCustomPredictionServiceInterceptor()) + client = PredictionServiceClient(transport=transport) + + + """ + def pre_predict(self, request: prediction_service.PredictRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[prediction_service.PredictRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for predict + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_predict(self, response: prediction_service.PredictResponse) -> prediction_service.PredictResponse: + """Post-rpc interceptor for predict + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class PredictionServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: PredictionServiceRestInterceptor + + +class PredictionServiceRestTransport(PredictionServiceTransport): + """REST backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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[PredictionServiceRestInterceptor] = 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 PredictionServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _Predict(PredictionServiceRestStub): + def __hash__(self): + return hash("Predict") + + __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: prediction_service.PredictRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> prediction_service.PredictResponse: + r"""Call the predict method over HTTP. + + Args: + request (~.prediction_service.PredictRequest): + The request object. Request message for Predict 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: + ~.prediction_service.PredictResponse: + Response message for predict method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{placement=projects/*/locations/*/catalogs/*/placements/*}:predict', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v2/{placement=projects/*/locations/*/catalogs/*/servingConfigs/*}:predict', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_predict(request, metadata) + pb_request = prediction_service.PredictRequest.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 = prediction_service.PredictResponse() + pb_resp = prediction_service.PredictResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_predict(resp) + return resp + + @property + def predict(self) -> Callable[ + [prediction_service.PredictRequest], + prediction_service.PredictResponse]: + # 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._Predict(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(PredictionServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(PredictionServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'PredictionServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__init__.py new file mode 100644 index 00000000..fee01226 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/__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 ProductServiceClient +from .async_client import ProductServiceAsyncClient + +__all__ = ( + 'ProductServiceClient', + 'ProductServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py new file mode 100644 index 00000000..8a12f4c4 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/async_client.py @@ -0,0 +1,1939 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.product_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product as gcr_product +from google.cloud.retail_v2.types import product_service +from google.cloud.retail_v2.types import promotion +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .client import ProductServiceClient + + +class ProductServiceAsyncClient: + """Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + """ + + _client: ProductServiceClient + + DEFAULT_ENDPOINT = ProductServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(ProductServiceClient.branch_path) + parse_branch_path = staticmethod(ProductServiceClient.parse_branch_path) + product_path = staticmethod(ProductServiceClient.product_path) + parse_product_path = staticmethod(ProductServiceClient.parse_product_path) + common_billing_account_path = staticmethod(ProductServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ProductServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ProductServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ProductServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ProductServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ProductServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ProductServiceClient.common_project_path) + parse_common_project_path = staticmethod(ProductServiceClient.parse_common_project_path) + common_location_path = staticmethod(ProductServiceClient.common_location_path) + parse_common_location_path = staticmethod(ProductServiceClient.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: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_info.__func__(ProductServiceAsyncClient, 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: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_file.__func__(ProductServiceAsyncClient, 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 ProductServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ProductServiceClient).get_transport_class, type(ProductServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ProductServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product service 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, ~.ProductServiceTransport]): 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 = ProductServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_product(self, + request: Optional[Union[product_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + async def sample_create_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.CreateProductRequest, dict]]): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + method. + parent (:class:`str`): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`google.cloud.retail_v2.types.Product`): + Required. The [Product][google.cloud.retail.v2.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`): + Required. The ID to use for the + [Product][google.cloud.retail.v2.Product], which will + become the final component of the + [Product.name][google.cloud.retail.v2.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2.Product]s with the same + [parent][google.cloud.retail.v2.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + 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.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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, + ) + + # Done; return the response. + return response + + async def get_product(self, + request: Optional[Union[product_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.Product: + r"""Gets a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + async def sample_get_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.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.retail_v2.types.GetProductRequest, dict]]): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + method. + name (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the requested + [Product][google.cloud.retail.v2.Product] does not + exist, a NOT_FOUND error is returned. + + 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.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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(( + ("name", request.name), + )), + ) + + # 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_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"""Gets a list of [Product][google.cloud.retail.v2.Product]s. + + .. 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 retail_v2 + + async def sample_list_products(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.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.retail_v2.types.ListProductsRequest, dict]]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + parent (:class:`str`): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2.Product]s under this + branch, regardless of whether or not this branch exists, + a PERMISSION_DENIED error is returned. + + 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.retail_v2.services.product_service.pagers.ListProductsAsyncPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.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_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_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, + ) + + # 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 update_product(self, + request: Optional[Union[product_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + async def sample_update_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.UpdateProductRequest( + product=product, + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateProductRequest, dict]]): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + method. + product (:class:`google.cloud.retail_v2.types.Product`): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + 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`): + Indicates which fields in the provided + [Product][google.cloud.retail.v2.Product] to update. The + immutable and output only fields are NOT supported. If + not set, all supported fields (the fields that are + neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask + path as "attributes.${key_name}". If a key name is + present in the mask but not in the patching product from + the request, this key will be deleted after the update. + + 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.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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(( + ("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_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"""Deletes a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + async def sample_delete_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.DeleteProductRequest, dict]]): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2.ProductService.DeleteProduct] + method. + name (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2.Product] to delete + can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] with more than + one + [variants][google.cloud.retail.v2.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2.Product] will be + deleted. + + 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_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_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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def import_products(self, + request: Optional[Union[import_config.ImportProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + .. 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 retail_v2 + + async def sample_import_products(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ImportProductsRequest, dict]]): + The request object. Request message for Import methods. + 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.retail_v2.types.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportProductsRequest(request) + + # 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_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.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, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def set_inventory(self, + request: Optional[Union[product_service.SetInventoryRequest, dict]] = None, + *, + inventory: Optional[product.Product] = None, + set_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]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2.Product] while respecting the + last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + .. 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 retail_v2 + + async def sample_set_inventory(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + inventory = retail_v2.Product() + inventory.title = "title_value" + + request = retail_v2.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.SetInventoryRequest, dict]]): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + method. + inventory (:class:`google.cloud.retail_v2.types.Product`): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is + returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product] named in + [Product.name][google.cloud.retail.v2.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + should be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + set_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2.Product] to update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_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.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + method. + + """ + # 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([inventory, set_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_service.SetInventoryRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_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.set_inventory, + 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(( + ("inventory.name", request.inventory.name), + )), + ) + + # 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_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + async def add_fulfillment_places(self, + request: Optional[Union[product_service.AddFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + async def sample_add_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.AddFulfillmentPlacesRequest, dict]]): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + 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.retail_v2.types.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.AddFulfillmentPlacesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places, + 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(( + ("product", request.product), + )), + ) + + # 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_service.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def remove_fulfillment_places(self, + request: Optional[Union[product_service.RemoveFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + async def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest, dict]]): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + 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.retail_v2.types.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.RemoveFulfillmentPlacesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places, + 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(( + ("product", request.product), + )), + ) + + # 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_service.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def add_local_inventories(self, + request: Optional[Union[product_service.AddLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + async def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.AddLocalInventoriesRequest, dict]]): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + 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.retail_v2.types.AddLocalInventoriesResponse` Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method. + + """ + # 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]) + 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_service.AddLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories, + 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(( + ("product", request.product), + )), + ) + + # 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_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + async def remove_local_inventories(self, + request: Optional[Union[product_service.RemoveLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + async def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.RemoveLocalInventoriesRequest, dict]]): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + 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.retail_v2.types.RemoveLocalInventoriesResponse` Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method. + + """ + # 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]) + 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_service.RemoveLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories, + 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(( + ("product", request.product), + )), + ) + + # 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_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductServiceAsyncClient": + 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__ = ( + "ProductServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py new file mode 100644 index 00000000..ec2d8fa8 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/client.py @@ -0,0 +1,2149 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.product_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product as gcr_product +from google.cloud.retail_v2.types import product_service +from google.cloud.retail_v2.types import promotion +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductServiceGrpcTransport +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .transports.rest import ProductServiceRestTransport + + +class ProductServiceClientMeta(type): + """Metaclass for the ProductService 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[ProductServiceTransport]] + _transport_registry["grpc"] = ProductServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ProductServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ProductServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ProductServiceTransport]: + """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 ProductServiceClient(metaclass=ProductServiceClientMeta): + """Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + """ + + @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 = "retail.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: + ProductServiceClient: 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: + ProductServiceClient: 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) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, ProductServiceTransport]] = 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 service 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, ProductServiceTransport]): 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, ProductServiceTransport): + # transport is a ProductServiceTransport 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(self, + request: Optional[Union[product_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + def sample_create_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.CreateProductRequest, dict]): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + method. + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (google.cloud.retail_v2.types.Product): + Required. The [Product][google.cloud.retail.v2.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): + Required. The ID to use for the + [Product][google.cloud.retail.v2.Product], which will + become the final component of the + [Product.name][google.cloud.retail.v2.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2.Product]s with the same + [parent][google.cloud.retail.v2.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + 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.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.CreateProductRequest): + request = product_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 get_product(self, + request: Optional[Union[product_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.Product: + r"""Gets a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + def sample_get_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetProductRequest, dict]): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + method. + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the requested + [Product][google.cloud.retail.v2.Product] does not + exist, a NOT_FOUND error is returned. + + 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.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.GetProductRequest): + request = product_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 list_products(self, + request: Optional[Union[product_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"""Gets a list of [Product][google.cloud.retail.v2.Product]s. + + .. 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 retail_v2 + + def sample_list_products(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.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.retail_v2.types.ListProductsRequest, dict]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2.Product]s under this + branch, regardless of whether or not this branch exists, + a PERMISSION_DENIED error is returned. + + 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.retail_v2.services.product_service.pagers.ListProductsPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.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_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_service.ListProductsRequest): + request = product_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 update_product(self, + request: Optional[Union[product_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + def sample_update_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.UpdateProductRequest( + product=product, + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateProductRequest, dict]): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + method. + product (google.cloud.retail_v2.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + 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): + Indicates which fields in the provided + [Product][google.cloud.retail.v2.Product] to update. The + immutable and output only fields are NOT supported. If + not set, all supported fields (the fields that are + neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask + path as "attributes.${key_name}". If a key name is + present in the mask but not in the patching product from + the request, this key will be deleted after the update. + + 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.retail_v2.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.UpdateProductRequest): + request = product_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_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"""Deletes a [Product][google.cloud.retail.v2.Product]. + + .. 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 retail_v2 + + def sample_delete_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + Args: + request (Union[google.cloud.retail_v2.types.DeleteProductRequest, dict]): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2.ProductService.DeleteProduct] + method. + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2.Product] to delete + can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] with more than + one + [variants][google.cloud.retail.v2.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2.Product] will be + deleted. + + 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_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_service.DeleteProductRequest): + request = product_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 import_products(self, + request: Optional[Union[import_config.ImportProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + .. 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 retail_v2 + + def sample_import_products(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + input_config = retail_v2.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ImportProductsRequest, dict]): + The request object. Request message for Import methods. + 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.retail_v2.types.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportProductsRequest): + request = import_config.ImportProductsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_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, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def set_inventory(self, + request: Optional[Union[product_service.SetInventoryRequest, dict]] = None, + *, + inventory: Optional[product.Product] = None, + set_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]] = (), + ) -> operation.Operation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2.Product] while respecting the + last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + .. 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 retail_v2 + + def sample_set_inventory(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + inventory = retail_v2.Product() + inventory.title = "title_value" + + request = retail_v2.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.SetInventoryRequest, dict]): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + method. + inventory (google.cloud.retail_v2.types.Product): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is + returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product] named in + [Product.name][google.cloud.retail.v2.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + should be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + set_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2.Product] to update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_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.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + method. + + """ + # 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([inventory, set_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_service.SetInventoryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.SetInventoryRequest): + request = product_service.SetInventoryRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_inventory] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("inventory.name", request.inventory.name), + )), + ) + + # 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_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + def add_fulfillment_places(self, + request: Optional[Union[product_service.AddFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + def sample_add_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.AddFulfillmentPlacesRequest, dict]): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.AddFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddFulfillmentPlacesRequest): + request = product_service.AddFulfillmentPlacesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def remove_fulfillment_places(self, + request: Optional[Union[product_service.RemoveFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest, dict]): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.RemoveFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveFulfillmentPlacesRequest): + request = product_service.RemoveFulfillmentPlacesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def add_local_inventories(self, + request: Optional[Union[product_service.AddLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.AddLocalInventoriesRequest, dict]): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.AddLocalInventoriesResponse` Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method. + + """ + # 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]) + 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_service.AddLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddLocalInventoriesRequest): + request = product_service.AddLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + def remove_local_inventories(self, + request: Optional[Union[product_service.RemoveLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2 + + def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.RemoveLocalInventoriesRequest, dict]): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.RemoveLocalInventoriesResponse` Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method. + + """ + # 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]) + 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_service.RemoveLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveLocalInventoriesRequest): + request = product_service.RemoveLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py new file mode 100644 index 00000000..308a4dcf --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import product +from google.cloud.retail_v2.types import product_service + + +class ListProductsPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.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.retail_v2.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_service.ListProductsResponse], + request: product_service.ListProductsRequest, + response: product_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.retail_v2.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2.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_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_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.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.retail_v2.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.retail_v2.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_service.ListProductsResponse]], + request: product_service.ListProductsRequest, + response: product_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.retail_v2.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2.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_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_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.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/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/__init__.py new file mode 100644 index 00000000..b9528228 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/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 ProductServiceTransport +from .grpc import ProductServiceGrpcTransport +from .grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .rest import ProductServiceRestTransport +from .rest import ProductServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ProductServiceTransport]] +_transport_registry['grpc'] = ProductServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ProductServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ProductServiceRestTransport + +__all__ = ( + 'ProductServiceTransport', + 'ProductServiceGrpcTransport', + 'ProductServiceGrpcAsyncIOTransport', + 'ProductServiceRestTransport', + 'ProductServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py new file mode 100644 index 00000000..0672892d --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/base.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product as gcr_product +from google.cloud.retail_v2.types import product_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 ProductServiceTransport(abc.ABC): + """Abstract transport class for ProductService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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: gapic_v1.method.wrap_method( + self.create_product, + default_timeout=None, + client_info=client_info, + ), + self.get_product: gapic_v1.method.wrap_method( + self.get_product, + default_timeout=None, + client_info=client_info, + ), + self.list_products: gapic_v1.method.wrap_method( + self.list_products, + default_timeout=None, + client_info=client_info, + ), + self.update_product: gapic_v1.method.wrap_method( + self.update_product, + default_timeout=None, + client_info=client_info, + ), + self.delete_product: gapic_v1.method.wrap_method( + self.delete_product, + default_timeout=None, + client_info=client_info, + ), + self.import_products: gapic_v1.method.wrap_method( + self.import_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.0, + client_info=client_info, + ), + self.set_inventory: gapic_v1.method.wrap_method( + self.set_inventory, + default_timeout=None, + client_info=client_info, + ), + self.add_fulfillment_places: gapic_v1.method.wrap_method( + self.add_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + self.remove_fulfillment_places: gapic_v1.method.wrap_method( + self.remove_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + self.add_local_inventories: gapic_v1.method.wrap_method( + self.add_local_inventories, + default_timeout=None, + client_info=client_info, + ), + self.remove_local_inventories: gapic_v1.method.wrap_method( + self.remove_local_inventories, + 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(self) -> Callable[ + [product_service.CreateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Union[ + product.Product, + Awaitable[product.Product] + ]]: + raise NotImplementedError() + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Union[ + product_service.ListProductsResponse, + Awaitable[product_service.ListProductsResponse] + ]]: + raise NotImplementedError() + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ProductServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py new file mode 100644 index 00000000..ff59097d --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc.py @@ -0,0 +1,764 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product as gcr_product +from google.cloud.retail_v2.types import product_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO + + +class ProductServiceGrpcTransport(ProductServiceTransport): + """gRPC backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + + 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 = 'retail.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 = 'retail.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(self) -> Callable[ + [product_service.CreateProductRequest], + gcr_product.Product]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + product.Product]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + product_service.ListProductsResponse]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2.Product]s. + + 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.retail.v2.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + gcr_product.Product]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + Returns: + Callable[[~.ImportProductsRequest], + ~.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_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + operations_pb2.Operation]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2.Product] while respecting the + last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + Returns: + Callable[[~.SetInventoryRequest], + ~.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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the add fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddFulfillmentPlacesRequest], + ~.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 'add_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveFulfillmentPlacesRequest], + ~.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 'remove_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + operations_pb2.Operation]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + ~.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 'add_local_inventories' not in self._stubs: + self._stubs['add_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/AddLocalInventories', + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_local_inventories'] + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + operations_pb2.Operation]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + ~.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 'remove_local_inventories' not in self._stubs: + self._stubs['remove_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/RemoveLocalInventories', + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_local_inventories'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ProductServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..e97baeb1 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/grpc_asyncio.py @@ -0,0 +1,763 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product as gcr_product +from google.cloud.retail_v2.types import product_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ProductServiceGrpcTransport + + +class ProductServiceGrpcAsyncIOTransport(ProductServiceTransport): + """gRPC AsyncIO backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + + 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 = 'retail.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 = 'retail.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(self) -> Callable[ + [product_service.CreateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Awaitable[product.Product]]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Awaitable[product_service.ListProductsResponse]]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2.Product]s. + + 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.retail.v2.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2.Product]. + + 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.retail.v2.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2.Product]s to be successfully + updated. + + Returns: + Callable[[~.ImportProductsRequest], + 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_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2.Product] while respecting the + last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + Returns: + Callable[[~.SetInventoryRequest], + 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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the add fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddFulfillmentPlacesRequest], + 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 'add_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveFulfillmentPlacesRequest], + 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 'remove_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places, + while respecting the last update timestamps of each inventory + field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + 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 'add_local_inventories' not in self._stubs: + self._stubs['add_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/AddLocalInventories', + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_local_inventories'] + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2.Product] at a list of places at + a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + 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 'remove_local_inventories' not in self._stubs: + self._stubs['remove_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ProductService/RemoveLocalInventories', + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_local_inventories'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ProductServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/rest.py new file mode 100644 index 00000000..e4b48d72 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/product_service/transports/rest.py @@ -0,0 +1,1731 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product as gcr_product +from google.cloud.retail_v2.types import product_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ProductServiceTransport, 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 ProductServiceRestInterceptor: + """Interceptor for ProductService. + + 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 ProductServiceRestTransport. + + .. code-block:: python + class MyCustomProductServiceInterceptor(ProductServiceRestInterceptor): + def pre_add_fulfillment_places(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_fulfillment_places(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_add_local_inventories(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_local_inventories(self, response): + logging.log(f"Received response: {response}") + return response + + 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_delete_product(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_import_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_products(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_remove_fulfillment_places(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_fulfillment_places(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_local_inventories(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_local_inventories(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_inventory(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_set_inventory(self, response): + logging.log(f"Received response: {response}") + return response + + 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 + + transport = ProductServiceRestTransport(interceptor=MyCustomProductServiceInterceptor()) + client = ProductServiceClient(transport=transport) + + + """ + def pre_add_fulfillment_places(self, request: product_service.AddFulfillmentPlacesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.AddFulfillmentPlacesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_fulfillment_places + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_add_fulfillment_places(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for add_fulfillment_places + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_add_local_inventories(self, request: product_service.AddLocalInventoriesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.AddLocalInventoriesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_local_inventories + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_add_local_inventories(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for add_local_inventories + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_create_product(self, request: product_service.CreateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_create_product(self, response: gcr_product.Product) -> gcr_product.Product: + """Post-rpc interceptor for create_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_delete_product(self, request: product_service.DeleteProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def pre_get_product(self, request: product_service.GetProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_get_product(self, response: product.Product) -> product.Product: + """Post-rpc interceptor for get_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_import_products(self, request: import_config.ImportProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_import_products(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_products + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_list_products(self, request: product_service.ListProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_list_products(self, response: product_service.ListProductsResponse) -> product_service.ListProductsResponse: + """Post-rpc interceptor for list_products + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_remove_fulfillment_places(self, request: product_service.RemoveFulfillmentPlacesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.RemoveFulfillmentPlacesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_fulfillment_places + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_remove_fulfillment_places(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for remove_fulfillment_places + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_remove_local_inventories(self, request: product_service.RemoveLocalInventoriesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.RemoveLocalInventoriesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_local_inventories + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_remove_local_inventories(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for remove_local_inventories + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_set_inventory(self, request: product_service.SetInventoryRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.SetInventoryRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_inventory + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_set_inventory(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for set_inventory + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_update_product(self, request: product_service.UpdateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_update_product(self, response: gcr_product.Product) -> gcr_product.Product: + """Post-rpc interceptor for update_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ProductServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ProductServiceRestInterceptor + + +class ProductServiceRestTransport(ProductServiceTransport): + """REST backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2.Product] + information of the customer's website. + + 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 = 'retail.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[ProductServiceRestInterceptor] = 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 ProductServiceRestInterceptor() + 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': '/v2/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*}/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="v2") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AddFulfillmentPlaces(ProductServiceRestStub): + def __hash__(self): + return hash("AddFulfillmentPlaces") + + __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_service.AddFulfillmentPlacesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the add fulfillment places method over HTTP. + + Args: + request (~.product_service.AddFulfillmentPlacesRequest): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + 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': '/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addFulfillmentPlaces', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_fulfillment_places(request, metadata) + pb_request = product_service.AddFulfillmentPlacesRequest.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_add_fulfillment_places(resp) + return resp + + class _AddLocalInventories(ProductServiceRestStub): + def __hash__(self): + return hash("AddLocalInventories") + + __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_service.AddLocalInventoriesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the add local inventories method over HTTP. + + Args: + request (~.product_service.AddLocalInventoriesRequest): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + 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': '/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addLocalInventories', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_local_inventories(request, metadata) + pb_request = product_service.AddLocalInventoriesRequest.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_add_local_inventories(resp) + return resp + + class _CreateProduct(ProductServiceRestStub): + def __hash__(self): + return hash("CreateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "productId" : "", } + + @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_service.CreateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_product.Product: + r"""Call the create product method over HTTP. + + Args: + request (~.product_service.CreateProductRequest): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.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: + ~.gcr_product.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*/branches/*}/products', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_create_product(request, metadata) + pb_request = product_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 = gcr_product.Product() + pb_resp = gcr_product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product(resp) + return resp + + class _DeleteProduct(ProductServiceRestStub): + 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_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_service.DeleteProductRequest): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2.ProductService.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': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + }, + ] + request, metadata = self._interceptor.pre_delete_product(request, metadata) + pb_request = product_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 _GetProduct(ProductServiceRestStub): + 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_service.GetProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product.Product: + r"""Call the get product method over HTTP. + + Args: + request (~.product_service.GetProductRequest): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.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.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + }, + ] + request, metadata = self._interceptor.pre_get_product(request, metadata) + pb_request = product_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.Product() + pb_resp = product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product(resp) + return resp + + class _ImportProducts(ProductServiceRestStub): + def __hash__(self): + return hash("ImportProducts") + + __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: import_config.ImportProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import products method over HTTP. + + Args: + request (~.import_config.ImportProductsRequest): + The request object. Request message for Import methods. + 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': '/v2/{parent=projects/*/locations/*/catalogs/*/branches/*}/products:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_products(request, metadata) + pb_request = import_config.ImportProductsRequest.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_products(resp) + return resp + + class _ListProducts(ProductServiceRestStub): + 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_service.ListProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_service.ListProductsResponse: + r"""Call the list products method over HTTP. + + Args: + request (~.product_service.ListProductsRequest): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.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_service.ListProductsResponse: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*/branches/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products(request, metadata) + pb_request = product_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_service.ListProductsResponse() + pb_resp = product_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 _RemoveFulfillmentPlaces(ProductServiceRestStub): + def __hash__(self): + return hash("RemoveFulfillmentPlaces") + + __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_service.RemoveFulfillmentPlacesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the remove fulfillment places method over HTTP. + + Args: + request (~.product_service.RemoveFulfillmentPlacesRequest): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + 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': '/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeFulfillmentPlaces', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_fulfillment_places(request, metadata) + pb_request = product_service.RemoveFulfillmentPlacesRequest.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_remove_fulfillment_places(resp) + return resp + + class _RemoveLocalInventories(ProductServiceRestStub): + def __hash__(self): + return hash("RemoveLocalInventories") + + __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_service.RemoveLocalInventoriesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the remove local inventories method over HTTP. + + Args: + request (~.product_service.RemoveLocalInventoriesRequest): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + 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': '/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeLocalInventories', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_local_inventories(request, metadata) + pb_request = product_service.RemoveLocalInventoriesRequest.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_remove_local_inventories(resp) + return resp + + class _SetInventory(ProductServiceRestStub): + def __hash__(self): + return hash("SetInventory") + + __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_service.SetInventoryRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the set inventory method over HTTP. + + Args: + request (~.product_service.SetInventoryRequest): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + 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': '/v2/{inventory.name=projects/*/locations/*/catalogs/*/branches/*/products/**}:setInventory', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_set_inventory(request, metadata) + pb_request = product_service.SetInventoryRequest.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_set_inventory(resp) + return resp + + class _UpdateProduct(ProductServiceRestStub): + 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_service.UpdateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_product.Product: + r"""Call the update product method over HTTP. + + Args: + request (~.product_service.UpdateProductRequest): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.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: + ~.gcr_product.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2/{product.name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_update_product(request, metadata) + pb_request = product_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 = gcr_product.Product() + pb_resp = gcr_product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product(resp) + return resp + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + 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._AddFulfillmentPlaces(self._session, self._host, self._interceptor) # type: ignore + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + 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._AddLocalInventories(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product(self) -> Callable[ + [product_service.CreateProductRequest], + gcr_product.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 delete_product(self) -> Callable[ + [product_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 get_product(self) -> Callable[ + [product_service.GetProductRequest], + product.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 import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + 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._ImportProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + product_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 remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + 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._RemoveFulfillmentPlaces(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + 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._RemoveLocalInventories(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + 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._SetInventory(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + gcr_product.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 get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ProductServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ProductServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ProductServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__init__.py new file mode 100644 index 00000000..0355170e --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/__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 SearchServiceClient +from .async_client import SearchServiceAsyncClient + +__all__ = ( + 'SearchServiceClient', + 'SearchServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.py new file mode 100644 index 00000000..1da0be1e --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/async_client.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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.search_service import pagers +from google.cloud.retail_v2.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .client import SearchServiceClient + + +class SearchServiceAsyncClient: + """Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + _client: SearchServiceClient + + DEFAULT_ENDPOINT = SearchServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SearchServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(SearchServiceClient.branch_path) + parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) + experiment_path = staticmethod(SearchServiceClient.experiment_path) + parse_experiment_path = staticmethod(SearchServiceClient.parse_experiment_path) + product_path = staticmethod(SearchServiceClient.product_path) + parse_product_path = staticmethod(SearchServiceClient.parse_product_path) + serving_config_path = staticmethod(SearchServiceClient.serving_config_path) + parse_serving_config_path = staticmethod(SearchServiceClient.parse_serving_config_path) + common_billing_account_path = staticmethod(SearchServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(SearchServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(SearchServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(SearchServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(SearchServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(SearchServiceClient.parse_common_organization_path) + common_project_path = staticmethod(SearchServiceClient.common_project_path) + parse_common_project_path = staticmethod(SearchServiceClient.parse_common_project_path) + common_location_path = staticmethod(SearchServiceClient.common_location_path) + parse_common_location_path = staticmethod(SearchServiceClient.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: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_info.__func__(SearchServiceAsyncClient, 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: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_file.__func__(SearchServiceAsyncClient, 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 SearchServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(SearchServiceClient).get_transport_class, type(SearchServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SearchServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service 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, ~.SearchServiceTransport]): 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 = SearchServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def search(self, + request: Optional[Union[search_service.SearchRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchAsyncPager: + r"""Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2 + + async def sample_search(): + # Create a client + client = retail_v2.SearchServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.SearchRequest, dict]]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + 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: + google.cloud.retail_v2.services.search_service.pagers.SearchAsyncPager: + Response message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.search, + 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(( + ("placement", request.placement), + )), + ) + + # 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.SearchAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SearchServiceAsyncClient": + 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__ = ( + "SearchServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py new file mode 100644 index 00000000..44065940 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/client.py @@ -0,0 +1,649 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.search_service import pagers +from google.cloud.retail_v2.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import SearchServiceGrpcTransport +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .transports.rest import SearchServiceRestTransport + + +class SearchServiceClientMeta(type): + """Metaclass for the SearchService 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[SearchServiceTransport]] + _transport_registry["grpc"] = SearchServiceGrpcTransport + _transport_registry["grpc_asyncio"] = SearchServiceGrpcAsyncIOTransport + _transport_registry["rest"] = SearchServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[SearchServiceTransport]: + """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 SearchServiceClient(metaclass=SearchServiceClientMeta): + """Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + @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 = "retail.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: + SearchServiceClient: 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: + SearchServiceClient: 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) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path(project: str,location: str,catalog: str,experiment: str,) -> str: + """Returns a fully-qualified experiment string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format(project=project, location=location, catalog=catalog, experiment=experiment, ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str,str]: + """Parses a experiment path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/experiments/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def serving_config_path(project: str,location: str,catalog: str,serving_config: str,) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str,str]: + """Parses a serving_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?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, SearchServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service 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, SearchServiceTransport]): 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, SearchServiceTransport): + # transport is a SearchServiceTransport 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 search(self, + request: Optional[Union[search_service.SearchRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchPager: + r"""Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2 + + def sample_search(): + # Create a client + client = retail_v2.SearchServiceClient() + + # Initialize request argument(s) + request = retail_v2.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.SearchRequest, dict]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + 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: + google.cloud.retail_v2.services.search_service.pagers.SearchPager: + Response message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a search_service.SearchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, search_service.SearchRequest): + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # 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.SearchPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SearchServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "SearchServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py new file mode 100644 index 00000000..824cb81f --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/pagers.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import search_service + + +class SearchPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.SearchResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.SearchResponse` + 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[..., search_service.SearchResponse], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + 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.retail_v2.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2.types.SearchResponse): + 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 = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[search_service.SearchResponse]: + 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[search_service.SearchResponse.SearchResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class SearchAsyncPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.SearchResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.SearchResponse` + 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[search_service.SearchResponse]], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + 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.retail_v2.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2.types.SearchResponse): + 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 = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[search_service.SearchResponse]: + 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[search_service.SearchResponse.SearchResult]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + 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/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/__init__.py new file mode 100644 index 00000000..4282aef0 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/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 SearchServiceTransport +from .grpc import SearchServiceGrpcTransport +from .grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .rest import SearchServiceRestTransport +from .rest import SearchServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[SearchServiceTransport]] +_transport_registry['grpc'] = SearchServiceGrpcTransport +_transport_registry['grpc_asyncio'] = SearchServiceGrpcAsyncIOTransport +_transport_registry['rest'] = SearchServiceRestTransport + +__all__ = ( + 'SearchServiceTransport', + 'SearchServiceGrpcTransport', + 'SearchServiceGrpcAsyncIOTransport', + 'SearchServiceRestTransport', + 'SearchServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py new file mode 100644 index 00000000..7f21f62d --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/base.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import search_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class SearchServiceTransport(abc.ABC): + """Abstract transport class for SearchService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.search: gapic_v1.method.wrap_method( + self.search, + 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 search(self) -> Callable[ + [search_service.SearchRequest], + Union[ + search_service.SearchResponse, + Awaitable[search_service.SearchResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'SearchServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py new file mode 100644 index 00000000..6d6d48af --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc.py @@ -0,0 +1,310 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO + + +class SearchServiceGrpcTransport(SearchServiceTransport): + """gRPC backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 search(self) -> Callable[ + [search_service.SearchRequest], + search_service.SearchResponse]: + r"""Return a callable for the search method over gRPC. + + Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.SearchRequest], + ~.SearchResponse]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'SearchServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..198292f2 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/grpc_asyncio.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import SearchServiceGrpcTransport + + +class SearchServiceGrpcAsyncIOTransport(SearchServiceTransport): + """gRPC AsyncIO backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 search(self) -> Callable[ + [search_service.SearchRequest], + Awaitable[search_service.SearchResponse]]: + r"""Return a callable for the search method over gRPC. + + Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.SearchRequest], + Awaitable[~.SearchResponse]]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'SearchServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/rest.py new file mode 100644 index 00000000..98871e13 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/search_service/transports/rest.py @@ -0,0 +1,504 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import search_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import SearchServiceTransport, 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 SearchServiceRestInterceptor: + """Interceptor for SearchService. + + 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 SearchServiceRestTransport. + + .. code-block:: python + class MyCustomSearchServiceInterceptor(SearchServiceRestInterceptor): + def pre_search(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_search(self, response): + logging.log(f"Received response: {response}") + return response + + transport = SearchServiceRestTransport(interceptor=MyCustomSearchServiceInterceptor()) + client = SearchServiceClient(transport=transport) + + + """ + def pre_search(self, request: search_service.SearchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[search_service.SearchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for search + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_search(self, response: search_service.SearchResponse) -> search_service.SearchResponse: + """Post-rpc interceptor for search + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class SearchServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: SearchServiceRestInterceptor + + +class SearchServiceRestTransport(SearchServiceTransport): + """REST backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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[SearchServiceRestInterceptor] = 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 SearchServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _Search(SearchServiceRestStub): + def __hash__(self): + return hash("Search") + + __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: search_service.SearchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> search_service.SearchResponse: + r"""Call the search method over HTTP. + + Args: + request (~.search_service.SearchRequest): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + 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: + ~.search_service.SearchResponse: + Response message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{placement=projects/*/locations/*/catalogs/*/placements/*}:search', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v2/{placement=projects/*/locations/*/catalogs/*/servingConfigs/*}:search', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_search(request, metadata) + pb_request = search_service.SearchRequest.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 = search_service.SearchResponse() + pb_resp = search_service.SearchResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_search(resp) + return resp + + @property + def search(self) -> Callable[ + [search_service.SearchRequest], + search_service.SearchResponse]: + # 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._Search(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(SearchServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(SearchServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'SearchServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/__init__.py new file mode 100644 index 00000000..3d167dee --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/__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 ServingConfigServiceClient +from .async_client import ServingConfigServiceAsyncClient + +__all__ = ( + 'ServingConfigServiceClient', + 'ServingConfigServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/async_client.py new file mode 100644 index 00000000..83013b4e --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/async_client.py @@ -0,0 +1,1098 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.serving_config_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import search_service +from google.cloud.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config as gcr_serving_config +from google.cloud.retail_v2.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .client import ServingConfigServiceClient + + +class ServingConfigServiceAsyncClient: + """Service for modifying ServingConfig.""" + + _client: ServingConfigServiceClient + + DEFAULT_ENDPOINT = ServingConfigServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ServingConfigServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ServingConfigServiceClient.catalog_path) + parse_catalog_path = staticmethod(ServingConfigServiceClient.parse_catalog_path) + serving_config_path = staticmethod(ServingConfigServiceClient.serving_config_path) + parse_serving_config_path = staticmethod(ServingConfigServiceClient.parse_serving_config_path) + common_billing_account_path = staticmethod(ServingConfigServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ServingConfigServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ServingConfigServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ServingConfigServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ServingConfigServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ServingConfigServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ServingConfigServiceClient.common_project_path) + parse_common_project_path = staticmethod(ServingConfigServiceClient.parse_common_project_path) + common_location_path = staticmethod(ServingConfigServiceClient.common_location_path) + parse_common_location_path = staticmethod(ServingConfigServiceClient.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: + ServingConfigServiceAsyncClient: The constructed client. + """ + return ServingConfigServiceClient.from_service_account_info.__func__(ServingConfigServiceAsyncClient, 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: + ServingConfigServiceAsyncClient: The constructed client. + """ + return ServingConfigServiceClient.from_service_account_file.__func__(ServingConfigServiceAsyncClient, 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 ServingConfigServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ServingConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ServingConfigServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ServingConfigServiceClient).get_transport_class, type(ServingConfigServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ServingConfigServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the serving config service 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, ~.ServingConfigServiceTransport]): 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 = ServingConfigServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_serving_config(self, + request: Optional[Union[serving_config_service.CreateServingConfigRequest, dict]] = None, + *, + parent: Optional[str] = None, + serving_config: Optional[gcr_serving_config.ServingConfig] = None, + serving_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + .. 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 retail_v2 + + async def sample_create_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = await client.create_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.CreateServingConfigRequest, dict]]): + The request object. Request for CreateServingConfig + method. + parent (:class:`str`): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config (:class:`google.cloud.retail_v2.types.ServingConfig`): + Required. The ServingConfig to + create. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config_id (:class:`str`): + Required. The ID to use for the ServingConfig, which + will become the final component of the ServingConfig's + resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``serving_config_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.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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, serving_config, serving_config_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 = serving_config_service.CreateServingConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if serving_config is not None: + request.serving_config = serving_config + if serving_config_id is not None: + request.serving_config_id = serving_config_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_serving_config, + 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, + ) + + # Done; return the response. + return response + + async def delete_serving_config(self, + request: Optional[Union[serving_config_service.DeleteServingConfigRequest, 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"""Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2 + + async def sample_delete_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_serving_config(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.DeleteServingConfigRequest, dict]]): + The request object. Request for DeleteServingConfig + method. + name (:class:`str`): + Required. The resource name of the ServingConfig to + delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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 = serving_config_service.DeleteServingConfigRequest(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_serving_config, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_serving_config(self, + request: Optional[Union[serving_config_service.UpdateServingConfigRequest, dict]] = None, + *, + serving_config: Optional[gcr_serving_config.ServingConfig] = 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]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Updates a ServingConfig. + + .. 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 retail_v2 + + async def sample_update_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = await client.update_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.UpdateServingConfigRequest, dict]]): + The request object. Request for UpdateServingConfig + method. + serving_config (:class:`google.cloud.retail_v2.types.ServingConfig`): + Required. The ServingConfig to + update. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2.ServingConfig] to + update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2.ServingConfig.name] + + If not set, all supported fields are updated. + + 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.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_config, 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 = serving_config_service.UpdateServingConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + 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_serving_config, + 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(( + ("serving_config.name", request.serving_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_serving_config(self, + request: Optional[Union[serving_config_service.GetServingConfigRequest, 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]] = (), + ) -> serving_config.ServingConfig: + r"""Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2 + + async def sample_get_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.GetServingConfigRequest, dict]]): + The request object. Request for GetServingConfig method. + name (:class:`str`): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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 = serving_config_service.GetServingConfigRequest(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_serving_config, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_serving_configs(self, + request: Optional[Union[serving_config_service.ListServingConfigsRequest, 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.ListServingConfigsAsyncPager: + r"""Lists all ServingConfigs linked to this catalog. + + .. 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 retail_v2 + + async def sample_list_serving_configs(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ListServingConfigsRequest, dict]]): + The request object. Request for ListServingConfigs + method. + parent (:class:`str`): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2.services.serving_config_service.pagers.ListServingConfigsAsyncPager: + Response for ListServingConfigs + 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 = serving_config_service.ListServingConfigsRequest(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_serving_configs, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListServingConfigsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_control(self, + request: Optional[Union[serving_config_service.AddControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + .. 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 retail_v2 + + async def sample_add_control(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.add_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.AddControlRequest, dict]]): + The request object. Request for AddControl method. + serving_config (:class:`str`): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 = serving_config_service.AddControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_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.add_control, + 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(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_control(self, + request: Optional[Union[serving_config_service.RemoveControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + .. 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 retail_v2 + + async def sample_remove_control(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.remove_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.RemoveControlRequest, dict]]): + The request object. Request for RemoveControl method. + serving_config (:class:`str`): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 = serving_config_service.RemoveControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_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.remove_control, + 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(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ServingConfigServiceAsyncClient": + 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__ = ( + "ServingConfigServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/client.py new file mode 100644 index 00000000..edfc41ca --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/client.py @@ -0,0 +1,1314 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.services.serving_config_service import pagers +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import search_service +from google.cloud.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config as gcr_serving_config +from google.cloud.retail_v2.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ServingConfigServiceGrpcTransport +from .transports.grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .transports.rest import ServingConfigServiceRestTransport + + +class ServingConfigServiceClientMeta(type): + """Metaclass for the ServingConfigService 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[ServingConfigServiceTransport]] + _transport_registry["grpc"] = ServingConfigServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ServingConfigServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ServingConfigServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ServingConfigServiceTransport]: + """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 ServingConfigServiceClient(metaclass=ServingConfigServiceClientMeta): + """Service for modifying ServingConfig.""" + + @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 = "retail.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: + ServingConfigServiceClient: 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: + ServingConfigServiceClient: 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) -> ServingConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ServingConfigServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def serving_config_path(project: str,location: str,catalog: str,serving_config: str,) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str,str]: + """Parses a serving_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?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, ServingConfigServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the serving config service 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, ServingConfigServiceTransport]): 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, ServingConfigServiceTransport): + # transport is a ServingConfigServiceTransport 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_serving_config(self, + request: Optional[Union[serving_config_service.CreateServingConfigRequest, dict]] = None, + *, + parent: Optional[str] = None, + serving_config: Optional[gcr_serving_config.ServingConfig] = None, + serving_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + .. 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 retail_v2 + + def sample_create_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = client.create_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.CreateServingConfigRequest, dict]): + The request object. Request for CreateServingConfig + method. + parent (str): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config (google.cloud.retail_v2.types.ServingConfig): + Required. The ServingConfig to + create. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config_id (str): + Required. The ID to use for the ServingConfig, which + will become the final component of the ServingConfig's + resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``serving_config_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.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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, serving_config, serving_config_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 serving_config_service.CreateServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.CreateServingConfigRequest): + request = serving_config_service.CreateServingConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if serving_config is not None: + request.serving_config = serving_config + if serving_config_id is not None: + request.serving_config_id = serving_config_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_serving_config] + + # 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_serving_config(self, + request: Optional[Union[serving_config_service.DeleteServingConfigRequest, 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"""Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2 + + def sample_delete_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_serving_config(request=request) + + Args: + request (Union[google.cloud.retail_v2.types.DeleteServingConfigRequest, dict]): + The request object. Request for DeleteServingConfig + method. + name (str): + Required. The resource name of the ServingConfig to + delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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 serving_config_service.DeleteServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.DeleteServingConfigRequest): + request = serving_config_service.DeleteServingConfigRequest(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_serving_config] + + # 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 update_serving_config(self, + request: Optional[Union[serving_config_service.UpdateServingConfigRequest, dict]] = None, + *, + serving_config: Optional[gcr_serving_config.ServingConfig] = 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]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Updates a ServingConfig. + + .. 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 retail_v2 + + def sample_update_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = client.update_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.UpdateServingConfigRequest, dict]): + The request object. Request for UpdateServingConfig + method. + serving_config (google.cloud.retail_v2.types.ServingConfig): + Required. The ServingConfig to + update. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2.ServingConfig] to + update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2.ServingConfig.name] + + If not set, all supported fields are updated. + + 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.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_config, 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 serving_config_service.UpdateServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.UpdateServingConfigRequest): + request = serving_config_service.UpdateServingConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + 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_serving_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config.name", request.serving_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_serving_config(self, + request: Optional[Union[serving_config_service.GetServingConfigRequest, 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]] = (), + ) -> serving_config.ServingConfig: + r"""Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2 + + def sample_get_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.GetServingConfigRequest, dict]): + The request object. Request for GetServingConfig method. + name (str): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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 serving_config_service.GetServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.GetServingConfigRequest): + request = serving_config_service.GetServingConfigRequest(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_serving_config] + + # 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 list_serving_configs(self, + request: Optional[Union[serving_config_service.ListServingConfigsRequest, 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.ListServingConfigsPager: + r"""Lists all ServingConfigs linked to this catalog. + + .. 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 retail_v2 + + def sample_list_serving_configs(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ListServingConfigsRequest, dict]): + The request object. Request for ListServingConfigs + method. + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2.services.serving_config_service.pagers.ListServingConfigsPager: + Response for ListServingConfigs + 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 serving_config_service.ListServingConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.ListServingConfigsRequest): + request = serving_config_service.ListServingConfigsRequest(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_serving_configs] + + # 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.ListServingConfigsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_control(self, + request: Optional[Union[serving_config_service.AddControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + .. 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 retail_v2 + + def sample_add_control(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.add_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.AddControlRequest, dict]): + The request object. Request for AddControl method. + serving_config (str): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 serving_config_service.AddControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.AddControlRequest): + request = serving_config_service.AddControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_control(self, + request: Optional[Union[serving_config_service.RemoveControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + .. 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 retail_v2 + + def sample_remove_control(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.remove_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.RemoveControlRequest, dict]): + The request object. Request for RemoveControl method. + serving_config (str): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 serving_config_service.RemoveControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.RemoveControlRequest): + request = serving_config_service.RemoveControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ServingConfigServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ServingConfigServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/pagers.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/pagers.py new file mode 100644 index 00000000..a0b93fed --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config_service + + +class ListServingConfigsPager: + """A pager for iterating through ``list_serving_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListServingConfigsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``serving_configs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListServingConfigs`` requests and continue to iterate + through the ``serving_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListServingConfigsResponse` + 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[..., serving_config_service.ListServingConfigsResponse], + request: serving_config_service.ListServingConfigsRequest, + response: serving_config_service.ListServingConfigsResponse, + *, + 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.retail_v2.types.ListServingConfigsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListServingConfigsResponse): + 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 = serving_config_service.ListServingConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[serving_config_service.ListServingConfigsResponse]: + 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[serving_config.ServingConfig]: + for page in self.pages: + yield from page.serving_configs + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListServingConfigsAsyncPager: + """A pager for iterating through ``list_serving_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2.types.ListServingConfigsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``serving_configs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListServingConfigs`` requests and continue to iterate + through the ``serving_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2.types.ListServingConfigsResponse` + 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[serving_config_service.ListServingConfigsResponse]], + request: serving_config_service.ListServingConfigsRequest, + response: serving_config_service.ListServingConfigsResponse, + *, + 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.retail_v2.types.ListServingConfigsRequest): + The initial request object. + response (google.cloud.retail_v2.types.ListServingConfigsResponse): + 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 = serving_config_service.ListServingConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[serving_config_service.ListServingConfigsResponse]: + 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[serving_config.ServingConfig]: + async def async_generator(): + async for page in self.pages: + for response in page.serving_configs: + 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/v2/google/cloud/retail_v2/services/serving_config_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/__init__.py new file mode 100644 index 00000000..e0440c46 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/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 ServingConfigServiceTransport +from .grpc import ServingConfigServiceGrpcTransport +from .grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .rest import ServingConfigServiceRestTransport +from .rest import ServingConfigServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ServingConfigServiceTransport]] +_transport_registry['grpc'] = ServingConfigServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ServingConfigServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ServingConfigServiceRestTransport + +__all__ = ( + 'ServingConfigServiceTransport', + 'ServingConfigServiceGrpcTransport', + 'ServingConfigServiceGrpcAsyncIOTransport', + 'ServingConfigServiceRestTransport', + 'ServingConfigServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/base.py new file mode 100644 index 00000000..a96cf4d3 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/base.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config as gcr_serving_config +from google.cloud.retail_v2.types import serving_config_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 ServingConfigServiceTransport(abc.ABC): + """Abstract transport class for ServingConfigService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_serving_config: gapic_v1.method.wrap_method( + self.create_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.delete_serving_config: gapic_v1.method.wrap_method( + self.delete_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.update_serving_config: gapic_v1.method.wrap_method( + self.update_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.get_serving_config: gapic_v1.method.wrap_method( + self.get_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.list_serving_configs: gapic_v1.method.wrap_method( + self.list_serving_configs, + default_timeout=None, + client_info=client_info, + ), + self.add_control: gapic_v1.method.wrap_method( + self.add_control, + default_timeout=None, + client_info=client_info, + ), + self.remove_control: gapic_v1.method.wrap_method( + self.remove_control, + 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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + Union[ + serving_config.ServingConfig, + Awaitable[serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + Union[ + serving_config_service.ListServingConfigsResponse, + Awaitable[serving_config_service.ListServingConfigsResponse] + ]]: + raise NotImplementedError() + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ServingConfigServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc.py new file mode 100644 index 00000000..32f76b35 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc.py @@ -0,0 +1,480 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config as gcr_serving_config +from google.cloud.retail_v2.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO + + +class ServingConfigServiceGrpcTransport(ServingConfigServiceTransport): + """gRPC backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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 = 'retail.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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the create serving config method over gRPC. + + Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + Returns: + Callable[[~.CreateServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['create_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/CreateServingConfig', + request_serializer=serving_config_service.CreateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['create_serving_config'] + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete serving config method over gRPC. + + Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.DeleteServingConfigRequest], + ~.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_serving_config' not in self._stubs: + self._stubs['delete_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/DeleteServingConfig', + request_serializer=serving_config_service.DeleteServingConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_serving_config'] + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the update serving config method over gRPC. + + Updates a ServingConfig. + + Returns: + Callable[[~.UpdateServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['update_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/UpdateServingConfig', + request_serializer=serving_config_service.UpdateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['update_serving_config'] + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + serving_config.ServingConfig]: + r"""Return a callable for the get serving config method over gRPC. + + Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.GetServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['get_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/GetServingConfig', + request_serializer=serving_config_service.GetServingConfigRequest.serialize, + response_deserializer=serving_config.ServingConfig.deserialize, + ) + return self._stubs['get_serving_config'] + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + serving_config_service.ListServingConfigsResponse]: + r"""Return a callable for the list serving configs method over gRPC. + + Lists all ServingConfigs linked to this catalog. + + Returns: + Callable[[~.ListServingConfigsRequest], + ~.ListServingConfigsResponse]: + 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_serving_configs' not in self._stubs: + self._stubs['list_serving_configs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/ListServingConfigs', + request_serializer=serving_config_service.ListServingConfigsRequest.serialize, + response_deserializer=serving_config_service.ListServingConfigsResponse.deserialize, + ) + return self._stubs['list_serving_configs'] + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the add control method over gRPC. + + Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + Returns: + Callable[[~.AddControlRequest], + ~.ServingConfig]: + 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_control' not in self._stubs: + self._stubs['add_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/AddControl', + request_serializer=serving_config_service.AddControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['add_control'] + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the remove control method over gRPC. + + Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + Returns: + Callable[[~.RemoveControlRequest], + ~.ServingConfig]: + 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_control' not in self._stubs: + self._stubs['remove_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/RemoveControl', + request_serializer=serving_config_service.RemoveControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['remove_control'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ServingConfigServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..fbadc979 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/grpc_asyncio.py @@ -0,0 +1,479 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config as gcr_serving_config +from google.cloud.retail_v2.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ServingConfigServiceGrpcTransport + + +class ServingConfigServiceGrpcAsyncIOTransport(ServingConfigServiceTransport): + """gRPC AsyncIO backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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 = 'retail.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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the create serving config method over gRPC. + + Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + Returns: + Callable[[~.CreateServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['create_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/CreateServingConfig', + request_serializer=serving_config_service.CreateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['create_serving_config'] + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete serving config method over gRPC. + + Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.DeleteServingConfigRequest], + 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_serving_config' not in self._stubs: + self._stubs['delete_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/DeleteServingConfig', + request_serializer=serving_config_service.DeleteServingConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_serving_config'] + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the update serving config method over gRPC. + + Updates a ServingConfig. + + Returns: + Callable[[~.UpdateServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['update_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/UpdateServingConfig', + request_serializer=serving_config_service.UpdateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['update_serving_config'] + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + Awaitable[serving_config.ServingConfig]]: + r"""Return a callable for the get serving config method over gRPC. + + Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.GetServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['get_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/GetServingConfig', + request_serializer=serving_config_service.GetServingConfigRequest.serialize, + response_deserializer=serving_config.ServingConfig.deserialize, + ) + return self._stubs['get_serving_config'] + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + Awaitable[serving_config_service.ListServingConfigsResponse]]: + r"""Return a callable for the list serving configs method over gRPC. + + Lists all ServingConfigs linked to this catalog. + + Returns: + Callable[[~.ListServingConfigsRequest], + Awaitable[~.ListServingConfigsResponse]]: + 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_serving_configs' not in self._stubs: + self._stubs['list_serving_configs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/ListServingConfigs', + request_serializer=serving_config_service.ListServingConfigsRequest.serialize, + response_deserializer=serving_config_service.ListServingConfigsResponse.deserialize, + ) + return self._stubs['list_serving_configs'] + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the add control method over gRPC. + + Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + Returns: + Callable[[~.AddControlRequest], + Awaitable[~.ServingConfig]]: + 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_control' not in self._stubs: + self._stubs['add_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/AddControl', + request_serializer=serving_config_service.AddControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['add_control'] + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the remove control method over gRPC. + + Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + Returns: + Callable[[~.RemoveControlRequest], + Awaitable[~.ServingConfig]]: + 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_control' not in self._stubs: + self._stubs['remove_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.ServingConfigService/RemoveControl', + request_serializer=serving_config_service.RemoveControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['remove_control'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ServingConfigServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/rest.py new file mode 100644 index 00000000..6ef11676 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/serving_config_service/transports/rest.py @@ -0,0 +1,1182 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config as gcr_serving_config +from google.cloud.retail_v2.types import serving_config_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ServingConfigServiceTransport, 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 ServingConfigServiceRestInterceptor: + """Interceptor for ServingConfigService. + + 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 ServingConfigServiceRestTransport. + + .. code-block:: python + class MyCustomServingConfigServiceInterceptor(ServingConfigServiceRestInterceptor): + def pre_add_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_serving_configs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_serving_configs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ServingConfigServiceRestTransport(interceptor=MyCustomServingConfigServiceInterceptor()) + client = ServingConfigServiceClient(transport=transport) + + + """ + def pre_add_control(self, request: serving_config_service.AddControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.AddControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_add_control(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for add_control + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_create_serving_config(self, request: serving_config_service.CreateServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.CreateServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_create_serving_config(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for create_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_delete_serving_config(self, request: serving_config_service.DeleteServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.DeleteServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def pre_get_serving_config(self, request: serving_config_service.GetServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.GetServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_get_serving_config(self, response: serving_config.ServingConfig) -> serving_config.ServingConfig: + """Post-rpc interceptor for get_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_list_serving_configs(self, request: serving_config_service.ListServingConfigsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.ListServingConfigsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_serving_configs + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_list_serving_configs(self, response: serving_config_service.ListServingConfigsResponse) -> serving_config_service.ListServingConfigsResponse: + """Post-rpc interceptor for list_serving_configs + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_remove_control(self, request: serving_config_service.RemoveControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.RemoveControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_remove_control(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for remove_control + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_update_serving_config(self, request: serving_config_service.UpdateServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.UpdateServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_update_serving_config(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for update_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ServingConfigServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ServingConfigServiceRestInterceptor + + +class ServingConfigServiceRestTransport(ServingConfigServiceTransport): + """REST backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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[ServingConfigServiceRestInterceptor] = 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 ServingConfigServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _AddControl(ServingConfigServiceRestStub): + def __hash__(self): + return hash("AddControl") + + __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: serving_config_service.AddControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the add control method over HTTP. + + Args: + request (~.serving_config_service.AddControlRequest): + The request object. Request for AddControl 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:addControl', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_control(request, metadata) + pb_request = serving_config_service.AddControlRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_add_control(resp) + return resp + + class _CreateServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("CreateServingConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "servingConfigId" : "", } + + @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: serving_config_service.CreateServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the create serving config method over HTTP. + + Args: + request (~.serving_config_service.CreateServingConfigRequest): + The request object. Request for CreateServingConfig + 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*}/servingConfigs', + 'body': 'serving_config', + }, + ] + request, metadata = self._interceptor.pre_create_serving_config(request, metadata) + pb_request = serving_config_service.CreateServingConfigRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_serving_config(resp) + return resp + + class _DeleteServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("DeleteServingConfig") + + __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: serving_config_service.DeleteServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete serving config method over HTTP. + + Args: + request (~.serving_config_service.DeleteServingConfigRequest): + The request object. Request for DeleteServingConfig + 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': '/v2/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_serving_config(request, metadata) + pb_request = serving_config_service.DeleteServingConfigRequest.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 _GetServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("GetServingConfig") + + __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: serving_config_service.GetServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> serving_config.ServingConfig: + r"""Call the get serving config method over HTTP. + + Args: + request (~.serving_config_service.GetServingConfigRequest): + The request object. Request for GetServingConfig 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: + ~.serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + }, + ] + request, metadata = self._interceptor.pre_get_serving_config(request, metadata) + pb_request = serving_config_service.GetServingConfigRequest.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 = serving_config.ServingConfig() + pb_resp = serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_serving_config(resp) + return resp + + class _ListServingConfigs(ServingConfigServiceRestStub): + def __hash__(self): + return hash("ListServingConfigs") + + __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: serving_config_service.ListServingConfigsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> serving_config_service.ListServingConfigsResponse: + r"""Call the list serving configs method over HTTP. + + Args: + request (~.serving_config_service.ListServingConfigsRequest): + The request object. Request for ListServingConfigs + 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: + ~.serving_config_service.ListServingConfigsResponse: + Response for ListServingConfigs + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*}/servingConfigs', + }, + ] + request, metadata = self._interceptor.pre_list_serving_configs(request, metadata) + pb_request = serving_config_service.ListServingConfigsRequest.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 = serving_config_service.ListServingConfigsResponse() + pb_resp = serving_config_service.ListServingConfigsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_serving_configs(resp) + return resp + + class _RemoveControl(ServingConfigServiceRestStub): + def __hash__(self): + return hash("RemoveControl") + + __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: serving_config_service.RemoveControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the remove control method over HTTP. + + Args: + request (~.serving_config_service.RemoveControlRequest): + The request object. Request for RemoveControl 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:removeControl', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_control(request, metadata) + pb_request = serving_config_service.RemoveControlRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_remove_control(resp) + return resp + + class _UpdateServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("UpdateServingConfig") + + __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: serving_config_service.UpdateServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the update serving config method over HTTP. + + Args: + request (~.serving_config_service.UpdateServingConfigRequest): + The request object. Request for UpdateServingConfig + 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2/{serving_config.name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + 'body': 'serving_config', + }, + ] + request, metadata = self._interceptor.pre_update_serving_config(request, metadata) + pb_request = serving_config_service.UpdateServingConfigRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_serving_config(resp) + return resp + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + gcr_serving_config.ServingConfig]: + # 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._AddControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + gcr_serving_config.ServingConfig]: + # 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._CreateServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + 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._DeleteServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + serving_config.ServingConfig]: + # 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._GetServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + serving_config_service.ListServingConfigsResponse]: + # 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._ListServingConfigs(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + gcr_serving_config.ServingConfig]: + # 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._RemoveControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + gcr_serving_config.ServingConfig]: + # 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._UpdateServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ServingConfigServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ServingConfigServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ServingConfigServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__init__.py new file mode 100644 index 00000000..387c002d --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/__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 UserEventServiceClient +from .async_client import UserEventServiceAsyncClient + +__all__ = ( + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py new file mode 100644 index 00000000..8a05405b --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/async_client.py @@ -0,0 +1,865 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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 import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .client import UserEventServiceClient + + +class UserEventServiceAsyncClient: + """Service for ingesting end user actions on the customer + website. + """ + + _client: UserEventServiceClient + + DEFAULT_ENDPOINT = UserEventServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = UserEventServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(UserEventServiceClient.catalog_path) + parse_catalog_path = staticmethod(UserEventServiceClient.parse_catalog_path) + product_path = staticmethod(UserEventServiceClient.product_path) + parse_product_path = staticmethod(UserEventServiceClient.parse_product_path) + common_billing_account_path = staticmethod(UserEventServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(UserEventServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(UserEventServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(UserEventServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(UserEventServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(UserEventServiceClient.parse_common_organization_path) + common_project_path = staticmethod(UserEventServiceClient.common_project_path) + parse_common_project_path = staticmethod(UserEventServiceClient.parse_common_project_path) + common_location_path = staticmethod(UserEventServiceClient.common_location_path) + parse_common_location_path = staticmethod(UserEventServiceClient.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: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_info.__func__(UserEventServiceAsyncClient, 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: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_file.__func__(UserEventServiceAsyncClient, 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 UserEventServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(UserEventServiceClient).get_transport_class, type(UserEventServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, UserEventServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service 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, ~.UserEventServiceTransport]): 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 = UserEventServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def write_user_event(self, + request: Optional[Union[user_event_service.WriteUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + .. 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 retail_v2 + + async def sample_write_user_event(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = await client.write_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.WriteUserEventRequest, dict]]): + The request object. Request message for WriteUserEvent + 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: + google.cloud.retail_v2.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.write_user_event, + 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, + ) + + # Done; return the response. + return response + + async def collect_user_event(self, + request: Optional[Union[user_event_service.CollectUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + .. 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 retail_v2 + + async def sample_collect_user_event(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = await client.collect_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.CollectUserEventRequest, dict]]): + The request object. Request message for CollectUserEvent + 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: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.collect_user_event, + 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, + ) + + # Done; return the response. + return response + + async def purge_user_events(self, + request: Optional[Union[purge_config.PurgeUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + .. 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 retail_v2 + + async def sample_purge_user_events(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.PurgeUserEventsRequest, dict]]): + The request object. Request message for PurgeUserEvents + 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: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + request = purge_config.PurgeUserEventsRequest(request) + + # 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_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.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, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + async def import_user_events(self, + request: Optional[Union[import_config.ImportUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + .. 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 retail_v2 + + async def sample_import_user_events(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.ImportUserEventsRequest, dict]]): + The request object. Request message for the + ImportUserEvents request. + 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.retail_v2.types.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportUserEventsRequest(request) + + # 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_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.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, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def rejoin_user_events(self, + request: Optional[Union[user_event_service.RejoinUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + .. 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 retail_v2 + + async def sample_rejoin_user_events(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2.types.RejoinUserEventsRequest, dict]]): + The request object. Request message for RejoinUserEvents + 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: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2.types.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.rejoin_user_events, + 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, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "UserEventServiceAsyncClient": + 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__ = ( + "UserEventServiceAsyncClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py new file mode 100644 index 00000000..9d55e160 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/client.py @@ -0,0 +1,1072 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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 import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserEventServiceGrpcTransport +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .transports.rest import UserEventServiceRestTransport + + +class UserEventServiceClientMeta(type): + """Metaclass for the UserEventService 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[UserEventServiceTransport]] + _transport_registry["grpc"] = UserEventServiceGrpcTransport + _transport_registry["grpc_asyncio"] = UserEventServiceGrpcAsyncIOTransport + _transport_registry["rest"] = UserEventServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[UserEventServiceTransport]: + """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 UserEventServiceClient(metaclass=UserEventServiceClientMeta): + """Service for ingesting end user actions on the customer + website. + """ + + @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 = "retail.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: + UserEventServiceClient: 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: + UserEventServiceClient: 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) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, UserEventServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service 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, UserEventServiceTransport]): 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, UserEventServiceTransport): + # transport is a UserEventServiceTransport 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 write_user_event(self, + request: Optional[Union[user_event_service.WriteUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + .. 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 retail_v2 + + def sample_write_user_event(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = client.write_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.WriteUserEventRequest, dict]): + The request object. Request message for WriteUserEvent + 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: + google.cloud.retail_v2.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.WriteUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.WriteUserEventRequest): + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.write_user_event] + + # 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 collect_user_event(self, + request: Optional[Union[user_event_service.CollectUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + .. 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 retail_v2 + + def sample_collect_user_event(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = client.collect_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.CollectUserEventRequest, dict]): + The request object. Request message for CollectUserEvent + 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: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.CollectUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.CollectUserEventRequest): + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.collect_user_event] + + # 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 purge_user_events(self, + request: Optional[Union[purge_config.PurgeUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + .. 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 retail_v2 + + def sample_purge_user_events(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.PurgeUserEventsRequest, dict]): + The request object. Request message for PurgeUserEvents + 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: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2.types.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a purge_config.PurgeUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, purge_config.PurgeUserEventsRequest): + request = purge_config.PurgeUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.purge_user_events] + + # 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, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + def import_user_events(self, + request: Optional[Union[import_config.ImportUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + .. 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 retail_v2 + + def sample_import_user_events(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + input_config = retail_v2.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.ImportUserEventsRequest, dict]): + The request object. Request message for the + ImportUserEvents request. + 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.retail_v2.types.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportUserEventsRequest): + request = import_config.ImportUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_user_events] + + # 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, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def rejoin_user_events(self, + request: Optional[Union[user_event_service.RejoinUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + .. 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 retail_v2 + + def sample_rejoin_user_events(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2.types.RejoinUserEventsRequest, dict]): + The request object. Request message for RejoinUserEvents + 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: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2.types.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.RejoinUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.RejoinUserEventsRequest): + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.rejoin_user_events] + + # 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, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "UserEventServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "UserEventServiceClient", +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/__init__.py new file mode 100644 index 00000000..bea95d5a --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/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 UserEventServiceTransport +from .grpc import UserEventServiceGrpcTransport +from .grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .rest import UserEventServiceRestTransport +from .rest import UserEventServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[UserEventServiceTransport]] +_transport_registry['grpc'] = UserEventServiceGrpcTransport +_transport_registry['grpc_asyncio'] = UserEventServiceGrpcAsyncIOTransport +_transport_registry['rest'] = UserEventServiceRestTransport + +__all__ = ( + 'UserEventServiceTransport', + 'UserEventServiceGrpcTransport', + 'UserEventServiceGrpcAsyncIOTransport', + 'UserEventServiceRestTransport', + 'UserEventServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py new file mode 100644 index 00000000..2a01b58e --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/base.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2 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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class UserEventServiceTransport(abc.ABC): + """Abstract transport class for UserEventService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.write_user_event: gapic_v1.method.wrap_method( + self.write_user_event, + default_timeout=None, + client_info=client_info, + ), + self.collect_user_event: gapic_v1.method.wrap_method( + self.collect_user_event, + default_timeout=None, + client_info=client_info, + ), + self.purge_user_events: gapic_v1.method.wrap_method( + self.purge_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.import_user_events: gapic_v1.method.wrap_method( + self.import_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.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.rejoin_user_events: gapic_v1.method.wrap_method( + self.rejoin_user_events, + 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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Union[ + user_event.UserEvent, + Awaitable[user_event.UserEvent] + ]]: + raise NotImplementedError() + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Union[ + httpbody_pb2.HttpBody, + Awaitable[httpbody_pb2.HttpBody] + ]]: + raise NotImplementedError() + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'UserEventServiceTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py new file mode 100644 index 00000000..e40dc098 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc.py @@ -0,0 +1,455 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO + + +class UserEventServiceGrpcTransport(UserEventServiceTransport): + """gRPC backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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 = 'retail.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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + user_event.UserEvent]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + ~.UserEvent]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + httpbody_pb2.HttpBody]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + ~.HttpBody]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + ~.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_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + Returns: + Callable[[~.ImportUserEventsRequest], + ~.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_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the rejoin user events method over gRPC. + + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + Returns: + Callable[[~.RejoinUserEventsRequest], + ~.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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'UserEventServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..0bbd17d4 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/grpc_asyncio.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. +# +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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import UserEventServiceGrpcTransport + + +class UserEventServiceGrpcAsyncIOTransport(UserEventServiceTransport): + """gRPC AsyncIO backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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 = 'retail.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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Awaitable[user_event.UserEvent]]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + Awaitable[~.UserEvent]]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Awaitable[httpbody_pb2.HttpBody]]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + Awaitable[~.HttpBody]]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + 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_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + Returns: + Callable[[~.ImportUserEventsRequest], + 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_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the rejoin user events method over gRPC. + + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + Returns: + Callable[[~.RejoinUserEventsRequest], + 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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'UserEventServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/rest.py b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/rest.py new file mode 100644 index 00000000..ba614e09 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/services/user_event_service/transports/rest.py @@ -0,0 +1,1082 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.api import httpbody_pb2 # type: ignore +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import UserEventServiceTransport, 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 UserEventServiceRestInterceptor: + """Interceptor for UserEventService. + + 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 UserEventServiceRestTransport. + + .. code-block:: python + class MyCustomUserEventServiceInterceptor(UserEventServiceRestInterceptor): + def pre_collect_user_event(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_collect_user_event(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_purge_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_purge_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_rejoin_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_rejoin_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_write_user_event(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_write_user_event(self, response): + logging.log(f"Received response: {response}") + return response + + transport = UserEventServiceRestTransport(interceptor=MyCustomUserEventServiceInterceptor()) + client = UserEventServiceClient(transport=transport) + + + """ + def pre_collect_user_event(self, request: user_event_service.CollectUserEventRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.CollectUserEventRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for collect_user_event + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_collect_user_event(self, response: httpbody_pb2.HttpBody) -> httpbody_pb2.HttpBody: + """Post-rpc interceptor for collect_user_event + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_import_user_events(self, request: import_config.ImportUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_import_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_purge_user_events(self, request: purge_config.PurgeUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[purge_config.PurgeUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for purge_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_purge_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for purge_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_rejoin_user_events(self, request: user_event_service.RejoinUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.RejoinUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for rejoin_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_rejoin_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for rejoin_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_write_user_event(self, request: user_event_service.WriteUserEventRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.WriteUserEventRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for write_user_event + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_write_user_event(self, response: user_event.UserEvent) -> user_event.UserEvent: + """Post-rpc interceptor for write_user_event + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class UserEventServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: UserEventServiceRestInterceptor + + +class UserEventServiceRestTransport(UserEventServiceTransport): + """REST backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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[UserEventServiceRestInterceptor] = 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 UserEventServiceRestInterceptor() + 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': '/v2/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2/{name=projects/*}/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="v2") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CollectUserEvent(UserEventServiceRestStub): + def __hash__(self): + return hash("CollectUserEvent") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "userEvent" : "", } + + @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: user_event_service.CollectUserEventRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> httpbody_pb2.HttpBody: + r"""Call the collect user event method over HTTP. + + Args: + request (~.user_event_service.CollectUserEventRequest): + The request object. Request message for CollectUserEvent + 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: + ~.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It + should only be used for payload formats that can't be + represented as JSON, such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as the + response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request fields + and also want access to the raw HTTP body. + + Example: + + :: + + message GetResourceRequest { + // A unique request id. + string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + :: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*}/userEvents:collect', + }, + ] + request, metadata = self._interceptor.pre_collect_user_event(request, metadata) + pb_request = user_event_service.CollectUserEventRequest.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 = httpbody_pb2.HttpBody() + pb_resp = resp + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_collect_user_event(resp) + return resp + + class _ImportUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("ImportUserEvents") + + __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: import_config.ImportUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import user events method over HTTP. + + Args: + request (~.import_config.ImportUserEventsRequest): + The request object. Request message for the + ImportUserEvents request. + 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': '/v2/{parent=projects/*/locations/*/catalogs/*}/userEvents:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_user_events(request, metadata) + pb_request = import_config.ImportUserEventsRequest.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_user_events(resp) + return resp + + class _PurgeUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("PurgeUserEvents") + + __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: purge_config.PurgeUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the purge user events method over HTTP. + + Args: + request (~.purge_config.PurgeUserEventsRequest): + The request object. Request message for PurgeUserEvents + 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': '/v2/{parent=projects/*/locations/*/catalogs/*}/userEvents:purge', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_purge_user_events(request, metadata) + pb_request = purge_config.PurgeUserEventsRequest.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_user_events(resp) + return resp + + class _RejoinUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("RejoinUserEvents") + + __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: user_event_service.RejoinUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the rejoin user events method over HTTP. + + Args: + request (~.user_event_service.RejoinUserEventsRequest): + The request object. Request message for RejoinUserEvents + 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': '/v2/{parent=projects/*/locations/*/catalogs/*}/userEvents:rejoin', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_rejoin_user_events(request, metadata) + pb_request = user_event_service.RejoinUserEventsRequest.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_rejoin_user_events(resp) + return resp + + class _WriteUserEvent(UserEventServiceRestStub): + def __hash__(self): + return hash("WriteUserEvent") + + __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: user_event_service.WriteUserEventRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> user_event.UserEvent: + r"""Call the write user event method over HTTP. + + Args: + request (~.user_event_service.WriteUserEventRequest): + The request object. Request message for WriteUserEvent + 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: + ~.user_event.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2/{parent=projects/*/locations/*/catalogs/*}/userEvents:write', + 'body': 'user_event', + }, + ] + request, metadata = self._interceptor.pre_write_user_event(request, metadata) + pb_request = user_event_service.WriteUserEventRequest.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 = user_event.UserEvent() + pb_resp = user_event.UserEvent.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_write_user_event(resp) + return resp + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + httpbody_pb2.HttpBody]: + # 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._CollectUserEvent(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + 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._ImportUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + 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._PurgeUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + 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._RejoinUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + user_event.UserEvent]: + # 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._WriteUserEvent(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(UserEventServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(UserEventServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'UserEventServiceRestTransport', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py new file mode 100644 index 00000000..e8e1cfcb --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/__init__.py @@ -0,0 +1,298 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 .catalog import ( + AttributesConfig, + Catalog, + CatalogAttribute, + CompletionConfig, + ProductLevelConfig, +) +from .catalog_service import ( + AddCatalogAttributeRequest, + GetAttributesConfigRequest, + GetCompletionConfigRequest, + GetDefaultBranchRequest, + GetDefaultBranchResponse, + ListCatalogsRequest, + ListCatalogsResponse, + RemoveCatalogAttributeRequest, + ReplaceCatalogAttributeRequest, + SetDefaultBranchRequest, + UpdateAttributesConfigRequest, + UpdateCatalogRequest, + UpdateCompletionConfigRequest, +) +from .common import ( + Audience, + ColorInfo, + Condition, + CustomAttribute, + FulfillmentInfo, + Image, + Interval, + LocalInventory, + PriceInfo, + Rating, + Rule, + UserInfo, + AttributeConfigLevel, + RecommendationsFilteringOption, + SearchSolutionUseCase, + SolutionType, +) +from .completion_service import ( + CompleteQueryRequest, + CompleteQueryResponse, +) +from .control import ( + Control, +) +from .control_service import ( + CreateControlRequest, + DeleteControlRequest, + GetControlRequest, + ListControlsRequest, + ListControlsResponse, + UpdateControlRequest, +) +from .import_config import ( + BigQuerySource, + CompletionDataInputConfig, + GcsSource, + ImportCompletionDataRequest, + ImportCompletionDataResponse, + ImportErrorsConfig, + ImportMetadata, + ImportProductsRequest, + ImportProductsResponse, + ImportUserEventsRequest, + ImportUserEventsResponse, + ProductInlineSource, + ProductInputConfig, + UserEventImportSummary, + UserEventInlineSource, + UserEventInputConfig, +) +from .model import ( + Model, +) +from .model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + GetModelRequest, + ListModelsRequest, + ListModelsResponse, + PauseModelRequest, + ResumeModelRequest, + TuneModelMetadata, + TuneModelRequest, + TuneModelResponse, + UpdateModelRequest, +) +from .prediction_service import ( + PredictRequest, + PredictResponse, +) +from .product import ( + Product, +) +from .product_service import ( + AddFulfillmentPlacesMetadata, + AddFulfillmentPlacesRequest, + AddFulfillmentPlacesResponse, + AddLocalInventoriesMetadata, + AddLocalInventoriesRequest, + AddLocalInventoriesResponse, + CreateProductRequest, + DeleteProductRequest, + GetProductRequest, + ListProductsRequest, + ListProductsResponse, + RemoveFulfillmentPlacesMetadata, + RemoveFulfillmentPlacesRequest, + RemoveFulfillmentPlacesResponse, + RemoveLocalInventoriesMetadata, + RemoveLocalInventoriesRequest, + RemoveLocalInventoriesResponse, + SetInventoryMetadata, + SetInventoryRequest, + SetInventoryResponse, + UpdateProductRequest, +) +from .promotion import ( + Promotion, +) +from .purge_config import ( + PurgeMetadata, + PurgeUserEventsRequest, + PurgeUserEventsResponse, +) +from .search_service import ( + ExperimentInfo, + SearchRequest, + SearchResponse, +) +from .serving_config import ( + ServingConfig, +) +from .serving_config_service import ( + AddControlRequest, + CreateServingConfigRequest, + DeleteServingConfigRequest, + GetServingConfigRequest, + ListServingConfigsRequest, + ListServingConfigsResponse, + RemoveControlRequest, + UpdateServingConfigRequest, +) +from .user_event import ( + CompletionDetail, + ProductDetail, + PurchaseTransaction, + UserEvent, +) +from .user_event_service import ( + CollectUserEventRequest, + RejoinUserEventsMetadata, + RejoinUserEventsRequest, + RejoinUserEventsResponse, + WriteUserEventRequest, +) + +__all__ = ( + 'AttributesConfig', + 'Catalog', + 'CatalogAttribute', + 'CompletionConfig', + 'ProductLevelConfig', + 'AddCatalogAttributeRequest', + 'GetAttributesConfigRequest', + 'GetCompletionConfigRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'RemoveCatalogAttributeRequest', + 'ReplaceCatalogAttributeRequest', + 'SetDefaultBranchRequest', + 'UpdateAttributesConfigRequest', + 'UpdateCatalogRequest', + 'UpdateCompletionConfigRequest', + 'Audience', + 'ColorInfo', + 'Condition', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'LocalInventory', + 'PriceInfo', + 'Rating', + 'Rule', + 'UserInfo', + 'AttributeConfigLevel', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'SolutionType', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'Control', + 'CreateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + 'UpdateControlRequest', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'Model', + 'CreateModelMetadata', + 'CreateModelRequest', + 'DeleteModelRequest', + 'GetModelRequest', + 'ListModelsRequest', + 'ListModelsResponse', + 'PauseModelRequest', + 'ResumeModelRequest', + 'TuneModelMetadata', + 'TuneModelRequest', + 'TuneModelResponse', + 'UpdateModelRequest', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'Promotion', + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'ExperimentInfo', + 'SearchRequest', + 'SearchResponse', + 'ServingConfig', + 'AddControlRequest', + 'CreateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'RemoveControlRequest', + 'UpdateServingConfigRequest', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py new file mode 100644 index 00000000..a20130d0 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog.py @@ -0,0 +1,539 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import common +from google.cloud.retail_v2.types import import_config + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'ProductLevelConfig', + 'CatalogAttribute', + 'AttributesConfig', + 'CompletionConfig', + 'Catalog', + }, +) + + +class ProductLevelConfig(proto.Message): + r"""Configures what level the product should be uploaded with + regards to how users will be send events and how predictions + will be made. + + Attributes: + ingestion_product_type (str): + The type of [Product][google.cloud.retail.v2.Product]s + allowed to be ingested into the catalog. Acceptable values + are: + + - ``primary`` (default): You can ingest + [Product][google.cloud.retail.v2.Product]s of all types. + When ingesting a + [Product][google.cloud.retail.v2.Product], its type will + default to + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + if unset. + - ``variant`` (incompatible with Retail Search): You can + only ingest + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s. This means + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id] + cannot be empty. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``variant`` and + [merchant_center_product_id_field][google.cloud.retail.v2.ProductLevelConfig.merchant_center_product_id_field] + is ``itemGroupId``, an INVALID_ARGUMENT error is returned. + + See `Product + levels `__ + for more details. + merchant_center_product_id_field (str): + Which field of `Merchant Center + Product `__ + should be imported as + [Product.id][google.cloud.retail.v2.Product.id]. Acceptable + values are: + + - ``offerId`` (default): Import ``offerId`` as the product + ID. + - ``itemGroupId``: Import ``itemGroupId`` as the product + ID. Notice that Retail API will choose one item from the + ones with the same ``itemGroupId``, and use it to + represent the item group. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``itemGroupId`` and + [ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type] + is ``variant``, an INVALID_ARGUMENT error is returned. + + See `Product + levels `__ + for more details. + """ + + ingestion_product_type: str = proto.Field( + proto.STRING, + number=1, + ) + merchant_center_product_id_field: str = proto.Field( + proto.STRING, + number=2, + ) + + +class CatalogAttribute(proto.Message): + r"""Catalog level attribute config for an attribute. For example, + if customers want to enable/disable facet for a specific + attribute. + + Attributes: + key (str): + Required. Attribute name. For example: ``color``, + ``brands``, ``attributes.custom_attribute``, such as + ``attributes.xyz``. To be indexable, the attribute name can + contain only alpha-numeric characters and underscores. For + example, an attribute named ``attributes.abc_xyz`` can be + indexed, but an attribute named ``attributes.abc-xyz`` + cannot be indexed. + + If the attribute key starts with ``attributes.``, then the + attribute is a custom attribute. Attributes such as + ``brands``, ``patterns``, and ``title`` are built-in and + called system attributes. + in_use (bool): + Output only. Indicates whether this attribute has been used + by any products. ``True`` if at least one + [Product][google.cloud.retail.v2.Product] is using this + attribute in + [Product.attributes][google.cloud.retail.v2.Product.attributes]. + Otherwise, this field is ``False``. + + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] + can be pre-loaded by using + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2.CatalogService.AddCatalogAttribute], + [CatalogService.ImportCatalogAttributes][], or + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2.CatalogService.UpdateAttributesConfig] + APIs. This field is ``False`` for pre-loaded + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute]s. + + Only pre-loaded [catalog + attributes][google.cloud.retail.v2.CatalogAttribute] that + are neither in use by products nor predefined can be + deleted. [Catalog + attributes][google.cloud.retail.v2.CatalogAttribute] that + are either in use by products or are predefined attributes + cannot be deleted; however, their configuration properties + will reset to default values upon removal request. + + After catalog changes, it takes about 10 minutes for this + field to update. + type_ (google.cloud.retail_v2.types.CatalogAttribute.AttributeType): + Output only. The type of this attribute. This is derived + from the attribute in + [Product.attributes][google.cloud.retail.v2.Product.attributes]. + indexable_option (google.cloud.retail_v2.types.CatalogAttribute.IndexableOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if INDEXABLE_ENABLED + attribute values are indexed so that it can be filtered, + faceted, or boosted in + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + Must be specified, otherwise throws INVALID_FORMAT error. + dynamic_facetable_option (google.cloud.retail_v2.types.CatalogAttribute.DynamicFacetableOption): + If DYNAMIC_FACETABLE_ENABLED, attribute values are available + for dynamic facet. Could only be DYNAMIC_FACETABLE_DISABLED + if + [CatalogAttribute.indexable_option][google.cloud.retail.v2.CatalogAttribute.indexable_option] + is INDEXABLE_DISABLED. Otherwise, an INVALID_ARGUMENT error + is returned. + + Must be specified, otherwise throws INVALID_FORMAT error. + searchable_option (google.cloud.retail_v2.types.CatalogAttribute.SearchableOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if SEARCHABLE_ENABLED, + attribute values are searchable by text queries in + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + If SEARCHABLE_ENABLED but attribute type is numerical, + attribute values will not be searchable by text queries in + [SearchService.Search][google.cloud.retail.v2.SearchService.Search], + as there are no text values associated to numerical + attributes. + + Must be specified, otherwise throws INVALID_FORMAT error. + exact_searchable_option (google.cloud.retail_v2.types.CatalogAttribute.ExactSearchableOption): + If EXACT_SEARCHABLE_ENABLED, attribute values will be exact + searchable. This property only applies to textual custom + attributes and requires indexable set to enabled to enable + exact-searchable. If unset, the server behavior defaults to + [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. + retrievable_option (google.cloud.retail_v2.types.CatalogAttribute.RetrievableOption): + If RETRIEVABLE_ENABLED, attribute values are retrievable in + the search results. If unset, the server behavior defaults + to + [RETRIEVABLE_DISABLED][google.cloud.retail.v2.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. + """ + class AttributeType(proto.Enum): + r"""The type of an attribute. + + Values: + UNKNOWN (0): + The type of the attribute is unknown. + + Used when type cannot be derived from attribute that is not + [in_use][google.cloud.retail.v2.CatalogAttribute.in_use]. + TEXTUAL (1): + Textual attribute. + NUMERICAL (2): + Numerical attribute. + """ + UNKNOWN = 0 + TEXTUAL = 1 + NUMERICAL = 2 + + class IndexableOption(proto.Enum): + r"""The status of the indexable option of a catalog attribute. + + Values: + INDEXABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + INDEXABLE_ENABLED (1): + Indexable option enabled for an attribute. + INDEXABLE_DISABLED (2): + Indexable option disabled for an attribute. + """ + INDEXABLE_OPTION_UNSPECIFIED = 0 + INDEXABLE_ENABLED = 1 + INDEXABLE_DISABLED = 2 + + class DynamicFacetableOption(proto.Enum): + r"""The status of the dynamic facetable option of a catalog + attribute. + + Values: + DYNAMIC_FACETABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + DYNAMIC_FACETABLE_ENABLED (1): + Dynamic facetable option enabled for an + attribute. + DYNAMIC_FACETABLE_DISABLED (2): + Dynamic facetable option disabled for an + attribute. + """ + DYNAMIC_FACETABLE_OPTION_UNSPECIFIED = 0 + DYNAMIC_FACETABLE_ENABLED = 1 + DYNAMIC_FACETABLE_DISABLED = 2 + + class SearchableOption(proto.Enum): + r"""The status of the searchable option of a catalog attribute. + + Values: + SEARCHABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + SEARCHABLE_ENABLED (1): + Searchable option enabled for an attribute. + SEARCHABLE_DISABLED (2): + Searchable option disabled for an attribute. + """ + SEARCHABLE_OPTION_UNSPECIFIED = 0 + SEARCHABLE_ENABLED = 1 + SEARCHABLE_DISABLED = 2 + + class ExactSearchableOption(proto.Enum): + r"""The status of the exact-searchable option of a catalog + attribute. + + Values: + EXACT_SEARCHABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + EXACT_SEARCHABLE_ENABLED (1): + Exact searchable option enabled for an + attribute. + EXACT_SEARCHABLE_DISABLED (2): + Exact searchable option disabled for an + attribute. + """ + EXACT_SEARCHABLE_OPTION_UNSPECIFIED = 0 + EXACT_SEARCHABLE_ENABLED = 1 + EXACT_SEARCHABLE_DISABLED = 2 + + class RetrievableOption(proto.Enum): + r"""The status of the retrievable option of a catalog attribute. + + Values: + RETRIEVABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + RETRIEVABLE_ENABLED (1): + Retrievable option enabled for an attribute. + RETRIEVABLE_DISABLED (2): + Retrievable option disabled for an attribute. + """ + RETRIEVABLE_OPTION_UNSPECIFIED = 0 + RETRIEVABLE_ENABLED = 1 + RETRIEVABLE_DISABLED = 2 + + key: str = proto.Field( + proto.STRING, + number=1, + ) + in_use: bool = proto.Field( + proto.BOOL, + number=9, + ) + type_: AttributeType = proto.Field( + proto.ENUM, + number=10, + enum=AttributeType, + ) + indexable_option: IndexableOption = proto.Field( + proto.ENUM, + number=5, + enum=IndexableOption, + ) + dynamic_facetable_option: DynamicFacetableOption = proto.Field( + proto.ENUM, + number=6, + enum=DynamicFacetableOption, + ) + searchable_option: SearchableOption = proto.Field( + proto.ENUM, + number=7, + enum=SearchableOption, + ) + exact_searchable_option: ExactSearchableOption = proto.Field( + proto.ENUM, + number=11, + enum=ExactSearchableOption, + ) + retrievable_option: RetrievableOption = proto.Field( + proto.ENUM, + number=12, + enum=RetrievableOption, + ) + + +class AttributesConfig(proto.Message): + r"""Catalog level attribute config. + + Attributes: + name (str): + Required. Immutable. The fully qualified resource name of + the attribute config. Format: + ``projects/*/locations/*/catalogs/*/attributesConfig`` + catalog_attributes (MutableMapping[str, google.cloud.retail_v2.types.CatalogAttribute]): + Enable attribute(s) config at catalog level. For example, + indexable, dynamic_facetable, or searchable for each + attribute. + + The key is catalog attribute's name. For example: ``color``, + ``brands``, ``attributes.custom_attribute``, such as + ``attributes.xyz``. + + The maximum number of catalog attributes allowed in a + request is 1000. + attribute_config_level (google.cloud.retail_v2.types.AttributeConfigLevel): + Output only. The + [AttributeConfigLevel][google.cloud.retail.v2.AttributeConfigLevel] + used for this catalog. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attributes: MutableMapping[str, 'CatalogAttribute'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message='CatalogAttribute', + ) + attribute_config_level: common.AttributeConfigLevel = proto.Field( + proto.ENUM, + number=3, + enum=common.AttributeConfigLevel, + ) + + +class CompletionConfig(proto.Message): + r"""Catalog level autocomplete config for customers to customize + autocomplete feature's settings. + + Attributes: + name (str): + Required. Immutable. Fully qualified name + ``projects/*/locations/*/catalogs/*/completionConfig`` + matching_order (str): + Specifies the matching order for autocomplete suggestions, + e.g., a query consisting of 'sh' with 'out-of-order' + specified would suggest "women's shoes", whereas a query of + 'red s' with 'exact-prefix' specified would suggest "red + shoes". Currently supported values: + + - 'out-of-order' + - 'exact-prefix' + + Default value: 'exact-prefix'. + max_suggestions (int): + The maximum number of autocomplete + suggestions returned per term. Default value is + 20. If left unset or set to 0, then will + fallback to default value. + + Value range is 1 to 20. + min_prefix_length (int): + The minimum number of characters needed to be + typed in order to get suggestions. Default value + is 2. If left unset or set to 0, then will + fallback to default value. + + Value range is 1 to 20. + auto_learning (bool): + If set to true, the auto learning function is enabled. Auto + learning uses user data to generate suggestions using ML + techniques. Default value is false. Only after enabling auto + learning can users use ``cloud-retail`` data in + [CompleteQueryRequest][google.cloud.retail.v2.CompleteQueryRequest]. + suggestions_input_config (google.cloud.retail_v2.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete suggestion phrases. + last_suggestions_import_operation (str): + Output only. Name of the LRO corresponding to the latest + suggestion terms list import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + denylist_input_config (google.cloud.retail_v2.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete denylist phrases. + last_denylist_import_operation (str): + Output only. Name of the LRO corresponding to the latest + denylist import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + allowlist_input_config (google.cloud.retail_v2.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete allowlist phrases. + last_allowlist_import_operation (str): + Output only. Name of the LRO corresponding to the latest + allowlist import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + matching_order: str = proto.Field( + proto.STRING, + number=2, + ) + max_suggestions: int = proto.Field( + proto.INT32, + number=3, + ) + min_prefix_length: int = proto.Field( + proto.INT32, + number=4, + ) + auto_learning: bool = proto.Field( + proto.BOOL, + number=11, + ) + suggestions_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=5, + message=import_config.CompletionDataInputConfig, + ) + last_suggestions_import_operation: str = proto.Field( + proto.STRING, + number=6, + ) + denylist_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=7, + message=import_config.CompletionDataInputConfig, + ) + last_denylist_import_operation: str = proto.Field( + proto.STRING, + number=8, + ) + allowlist_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=9, + message=import_config.CompletionDataInputConfig, + ) + last_allowlist_import_operation: str = proto.Field( + proto.STRING, + number=10, + ) + + +class Catalog(proto.Message): + r"""The catalog configuration. + + Attributes: + name (str): + Required. Immutable. The fully qualified + resource name of the catalog. + display_name (str): + Required. Immutable. The catalog display name. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + product_level_config (google.cloud.retail_v2.types.ProductLevelConfig): + Required. The product level configuration. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + product_level_config: 'ProductLevelConfig' = proto.Field( + proto.MESSAGE, + number=4, + message='ProductLevelConfig', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py new file mode 100644 index 00000000..94484220 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/catalog_service.py @@ -0,0 +1,457 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import catalog as gcr_catalog +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'UpdateCatalogRequest', + 'SetDefaultBranchRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'GetCompletionConfigRequest', + 'UpdateCompletionConfigRequest', + 'GetAttributesConfigRequest', + 'UpdateAttributesConfigRequest', + 'AddCatalogAttributeRequest', + 'RemoveCatalogAttributeRequest', + 'ReplaceCatalogAttributeRequest', + }, +) + + +class ListCatalogsRequest(proto.Message): + r"""Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + + Attributes: + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2.Catalog]s under this + location, regardless of whether or not this location exists, + a PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of [Catalog][google.cloud.retail.v2.Catalog]s + to return. If unspecified, defaults to 50. The maximum + allowed value is 1000. Values above 1000 will be coerced to + 1000. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [ListCatalogsResponse.next_page_token][google.cloud.retail.v2.ListCatalogsResponse.next_page_token], + received from a previous + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + """ + + 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 ListCatalogsResponse(proto.Message): + r"""Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2.CatalogService.ListCatalogs] + method. + + Attributes: + catalogs (MutableSequence[google.cloud.retail_v2.types.Catalog]): + All the customer's + [Catalog][google.cloud.retail.v2.Catalog]s. + next_page_token (str): + A token that can be sent as + [ListCatalogsRequest.page_token][google.cloud.retail.v2.ListCatalogsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + catalogs: MutableSequence[gcr_catalog.Catalog] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class UpdateCatalogRequest(proto.Message): + r"""Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2.CatalogService.UpdateCatalog] + method. + + Attributes: + catalog (google.cloud.retail_v2.types.Catalog): + Required. The [Catalog][google.cloud.retail.v2.Catalog] to + update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2.Catalog], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2.Catalog] to update + does not exist, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + """ + + catalog: gcr_catalog.Catalog = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class SetDefaultBranchRequest(proto.Message): + r"""Request message to set a specified branch as new default_branch. + + Attributes: + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + branch_id (str): + The final component of the resource name of a branch. + + This field must be one of "0", "1" or "2". Otherwise, an + INVALID_ARGUMENT error is returned. + + If there are no sufficient active products in the targeted + branch and + [force][google.cloud.retail.v2.SetDefaultBranchRequest.force] + is not set, a FAILED_PRECONDITION error is returned. + note (str): + Some note on this request, this can be retrieved by + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch] + before next valid default branch set occurs. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + force (bool): + If set to true, it permits switching to a branch with + [branch_id][google.cloud.retail.v2.SetDefaultBranchRequest.branch_id] + even if it has no sufficient active products. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + branch_id: str = proto.Field( + proto.STRING, + number=2, + ) + note: str = proto.Field( + proto.STRING, + number=3, + ) + force: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class GetDefaultBranchRequest(proto.Message): + r"""Request message to show which branch is currently the default + branch. + + Attributes: + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetDefaultBranchResponse(proto.Message): + r"""Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2.CatalogService.GetDefaultBranch]. + + Attributes: + branch (str): + Full resource name of the branch id currently + set as default branch. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when this branch is set to default. + note (str): + This corresponds to + [SetDefaultBranchRequest.note][google.cloud.retail.v2.SetDefaultBranchRequest.note] + field, when this branch was set as default. + """ + + branch: str = proto.Field( + proto.STRING, + number=1, + ) + set_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + note: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetCompletionConfigRequest(proto.Message): + r"""Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2.CatalogService.GetCompletionConfig] + method. + + Attributes: + name (str): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateCompletionConfigRequest(proto.Message): + r"""Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2.CatalogService.UpdateCompletionConfig] + method. + + Attributes: + completion_config (google.cloud.retail_v2.types.CompletionConfig): + Required. The + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + """ + + completion_config: gcr_catalog.CompletionConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.CompletionConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetAttributesConfigRequest(proto.Message): + r"""Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2.CatalogService.GetAttributesConfig] + method. + + Attributes: + name (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateAttributesConfigRequest(proto.Message): + r"""Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2.CatalogService.UpdateAttributesConfig] + method. + + Attributes: + attributes_config (google.cloud.retail_v2.types.AttributesConfig): + Required. The + [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + """ + + attributes_config: gcr_catalog.AttributesConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.AttributesConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class AddCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2.CatalogService.AddCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + catalog_attribute (google.cloud.retail_v2.types.CatalogAttribute): + Required. The + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] + to add. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attribute: gcr_catalog.CatalogAttribute = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_catalog.CatalogAttribute, + ) + + +class RemoveCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + key (str): + Required. The attribute name key of the + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] + to remove. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + key: str = proto.Field( + proto.STRING, + number=2, + ) + + +class ReplaceCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + catalog_attribute (google.cloud.retail_v2.types.CatalogAttribute): + Required. The updated + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute]. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] + to update. The following are NOT supported: + + - [CatalogAttribute.key][google.cloud.retail.v2.CatalogAttribute.key] + + If not set, all supported fields are updated. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attribute: gcr_catalog.CatalogAttribute = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_catalog.CatalogAttribute, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=3, + message=field_mask_pb2.FieldMask, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py new file mode 100644 index 00000000..964ea53e --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/common.py @@ -0,0 +1,1255 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'AttributeConfigLevel', + 'SolutionType', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'Condition', + 'Rule', + 'Audience', + 'ColorInfo', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'PriceInfo', + 'Rating', + 'UserInfo', + 'LocalInventory', + }, +) + + +class AttributeConfigLevel(proto.Enum): + r"""At which level we offer configuration for attributes. + + Values: + ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED (0): + Value used when unset. In this case, server behavior + defaults to + [CATALOG_LEVEL_ATTRIBUTE_CONFIG][google.cloud.retail.v2.AttributeConfigLevel.CATALOG_LEVEL_ATTRIBUTE_CONFIG]. + PRODUCT_LEVEL_ATTRIBUTE_CONFIG (1): + At this level, we honor the attribute configurations set in + [Product.attributes][google.cloud.retail.v2.Product.attributes]. + CATALOG_LEVEL_ATTRIBUTE_CONFIG (2): + At this level, we honor the attribute configurations set in + [CatalogConfig.attribute_configs][]. + """ + ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED = 0 + PRODUCT_LEVEL_ATTRIBUTE_CONFIG = 1 + CATALOG_LEVEL_ATTRIBUTE_CONFIG = 2 + + +class SolutionType(proto.Enum): + r"""The type of solution. + + Values: + SOLUTION_TYPE_UNSPECIFIED (0): + Default value. + SOLUTION_TYPE_RECOMMENDATION (1): + Used for Recommendations AI. + SOLUTION_TYPE_SEARCH (2): + Used for Retail Search. + """ + SOLUTION_TYPE_UNSPECIFIED = 0 + SOLUTION_TYPE_RECOMMENDATION = 1 + SOLUTION_TYPE_SEARCH = 2 + + +class RecommendationsFilteringOption(proto.Enum): + r"""If filtering for recommendations is enabled. + + Values: + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED (0): + Value used when unset. In this case, server behavior + defaults to + [RECOMMENDATIONS_FILTERING_DISABLED][google.cloud.retail.v2.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED]. + RECOMMENDATIONS_FILTERING_DISABLED (1): + Recommendation filtering is disabled. + RECOMMENDATIONS_FILTERING_ENABLED (3): + Recommendation filtering is enabled. + """ + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED = 0 + RECOMMENDATIONS_FILTERING_DISABLED = 1 + RECOMMENDATIONS_FILTERING_ENABLED = 3 + + +class SearchSolutionUseCase(proto.Enum): + r"""The use case of Cloud Retail Search. + + Values: + SEARCH_SOLUTION_USE_CASE_UNSPECIFIED (0): + The value when it's unspecified. In this case, server + behavior defaults to + [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH]. + SEARCH_SOLUTION_USE_CASE_SEARCH (1): + Search use case. Expects the traffic has a non-empty + [query][google.cloud.retail.v2.SearchRequest.query]. + SEARCH_SOLUTION_USE_CASE_BROWSE (2): + Browse use case. Expects the traffic has an empty + [query][google.cloud.retail.v2.SearchRequest.query]. + """ + SEARCH_SOLUTION_USE_CASE_UNSPECIFIED = 0 + SEARCH_SOLUTION_USE_CASE_SEARCH = 1 + SEARCH_SOLUTION_USE_CASE_BROWSE = 2 + + +class Condition(proto.Message): + r"""Metadata that is used to define a condition that triggers an action. + A valid condition must specify at least one of 'query_terms' or + 'products_filter'. If multiple fields are specified, the condition + is met if all the fields are satisfied e.g. if a set of query terms + and product_filter are set, then only items matching the + product_filter for requests with a query matching the query terms + wil get boosted. + + Attributes: + query_terms (MutableSequence[google.cloud.retail_v2.types.Condition.QueryTerm]): + A list (up to 10 entries) of terms to match + the query on. If not specified, match all + queries. If many query terms are specified, the + condition is matched if any of the terms is a + match (i.e. using the OR operator). + active_time_range (MutableSequence[google.cloud.retail_v2.types.Condition.TimeRange]): + Range of time(s) specifying when Condition is + active. Condition true if any time range + matches. + """ + + class QueryTerm(proto.Message): + r"""Query terms that we want to match on. + + Attributes: + value (str): + The value of the term to match on. + Value cannot be empty. + Value can have at most 3 terms if specified as a + partial match. Each space separated string is + considered as one term. For example, "a b c" is + 3 terms and allowed, but " a b c d" is 4 terms + and not allowed for a partial match. + full_match (bool): + Whether this is supposed to be a full or + partial match. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + ) + full_match: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TimeRange(proto.Message): + r"""Used for time-dependent conditions. + Example: Want to have rule applied for week long sale. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Start of time range. Range is inclusive. + end_time (google.protobuf.timestamp_pb2.Timestamp): + End of time range. Range is inclusive. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + query_terms: MutableSequence[QueryTerm] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=QueryTerm, + ) + active_time_range: MutableSequence[TimeRange] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=TimeRange, + ) + + +class Rule(proto.Message): + r"""A rule is a condition-action pair + + - A condition defines when a rule is to be triggered. + - An action specifies what occurs on that trigger. Currently rules + only work for [controls][google.cloud.retail.v2.Control] with + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]. + + 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: + boost_action (google.cloud.retail_v2.types.Rule.BoostAction): + A boost action. + + This field is a member of `oneof`_ ``action``. + redirect_action (google.cloud.retail_v2.types.Rule.RedirectAction): + Redirects a shopper to a specific page. + + This field is a member of `oneof`_ ``action``. + oneway_synonyms_action (google.cloud.retail_v2.types.Rule.OnewaySynonymsAction): + Treats specific term as a synonym with a + group of terms. Group of terms will not be + treated as synonyms with the specific term. + + This field is a member of `oneof`_ ``action``. + do_not_associate_action (google.cloud.retail_v2.types.Rule.DoNotAssociateAction): + Prevents term from being associated with + other terms. + + This field is a member of `oneof`_ ``action``. + replacement_action (google.cloud.retail_v2.types.Rule.ReplacementAction): + Replaces specific terms in the query. + + This field is a member of `oneof`_ ``action``. + ignore_action (google.cloud.retail_v2.types.Rule.IgnoreAction): + Ignores specific terms from query during + search. + + This field is a member of `oneof`_ ``action``. + filter_action (google.cloud.retail_v2.types.Rule.FilterAction): + Filters results. + + This field is a member of `oneof`_ ``action``. + twoway_synonyms_action (google.cloud.retail_v2.types.Rule.TwowaySynonymsAction): + Treats a set of terms as synonyms of one + another. + + This field is a member of `oneof`_ ``action``. + condition (google.cloud.retail_v2.types.Condition): + Required. The condition that triggers the + rule. If the condition is empty, the rule will + always apply. + """ + + class BoostAction(proto.Message): + r"""A boost action to apply to results matching condition + specified above. + + Attributes: + boost (float): + Strength of the condition boost, which must be in [-1, 1]. + Negative boost means demotion. Default is 0.0. + + Setting to 1.0 gives the item a big promotion. However, it + does not necessarily mean that the boosted item will be the + top result at all times, nor that other items will be + excluded. Results could still be shown even when none of + them matches the condition. And results that are + significantly more relevant to the search query can still + trump your heavily favored but irrelevant items. + + Setting to -1.0 gives the item a big demotion. However, + results that are deeply relevant might still be shown. The + item will have an upstream battle to get a fairly high + ranking, but it is not blocked out completely. + + Setting to 0.0 means no boost applied. The boosting + condition is ignored. + products_filter (str): + The filter can have a max size of 5000 characters. An + expression which specifies which products to apply an action + to. The syntax and supported fields are the same as a filter + expression. See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for detail syntax and limitations. + + Examples: + + - To boost products with product ID "product_1" or + "product_2", and color "Red" or "Blue": *(id: + ANY("product_1", "product_2"))* *AND* *(colorFamilies: + ANY("Red", "Blue"))* + """ + + boost: float = proto.Field( + proto.FLOAT, + number=1, + ) + products_filter: str = proto.Field( + proto.STRING, + number=2, + ) + + class FilterAction(proto.Message): + r"""- Rule Condition: + + - No + [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms] + provided is a global match. + - 1 or more + [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms] + provided are combined with OR operator. + + - Action Input: The request query and filter that are applied to + the retrieved products, in addition to any filters already + provided with the SearchRequest. The AND operator is used to + combine the query's existing filters with the filter rule(s). + NOTE: May result in 0 results when filters conflict. + - Action Result: Filters the returned objects to be ONLY those that + passed the filter. + + Attributes: + filter (str): + A filter to apply on the matching condition results. + Supported features: + + - [filter][google.cloud.retail.v2.Rule.FilterAction.filter] + must be set. + - Filter syntax is identical to + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter]. + See more details at the Retail Search `user + guide `__. + - To filter products with product ID "product_1" or + "product_2", and color "Red" or "Blue": *(id: + ANY("product_1", "product_2"))* *AND* *(colorFamilies: + ANY("Red", "Blue"))* + """ + + filter: str = proto.Field( + proto.STRING, + number=1, + ) + + class RedirectAction(proto.Message): + r"""Redirects a shopper to a specific page. + + - Rule Condition: + + - Must specify + [Condition.query_terms][google.cloud.retail.v2.Condition.query_terms]. + + - Action Input: Request Query + - Action Result: Redirects shopper to provided uri. + + Attributes: + redirect_uri (str): + URL must have length equal or less than 2000 + characters. + """ + + redirect_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + class TwowaySynonymsAction(proto.Message): + r"""Creates a set of terms that will be treated as synonyms of each + other. Example: synonyms of "sneakers" and "shoes": + + - "sneakers" will use a synonym of "shoes". + - "shoes" will use a synonym of "sneakers". + + Attributes: + synonyms (MutableSequence[str]): + Defines a set of synonyms. + Can specify up to 100 synonyms. + Must specify at least 2 synonyms. + """ + + synonyms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class OnewaySynonymsAction(proto.Message): + r"""Maps a set of terms to a set of synonyms. Set of synonyms will be + treated as synonyms of each query term only. ``query_terms`` will + not be treated as synonyms of each other. Example: "sneakers" will + use a synonym of "shoes". "shoes" will not use a synonym of + "sneakers". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. + Will treat synonyms as their synonyms. + Not themselves synonyms of the synonyms. + Can specify up to 100 terms. + synonyms (MutableSequence[str]): + Defines a set of synonyms. + Cannot contain duplicates. + Can specify up to 100 synonyms. + oneway_terms (MutableSequence[str]): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + synonyms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + oneway_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + class DoNotAssociateAction(proto.Message): + r"""Prevents ``query_term`` from being associated with specified terms + during search. Example: Don't associate "gShoe" and "cheap". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. Will not consider + do_not_associate_terms for search if in search query. Can + specify up to 100 terms. + do_not_associate_terms (MutableSequence[str]): + Cannot contain duplicates or the query term. + Can specify up to 100 terms. + terms (MutableSequence[str]): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + do_not_associate_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class ReplacementAction(proto.Message): + r"""Replaces a term in the query. Multiple replacement candidates can be + specified. All ``query_terms`` will be replaced with the replacement + term. Example: Replace "gShoe" with "google shoe". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. + Will be replaced by replacement term. + Can specify up to 100 terms. + replacement_term (str): + Term that will be used for replacement. + term (str): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + replacement_term: str = proto.Field( + proto.STRING, + number=3, + ) + term: str = proto.Field( + proto.STRING, + number=1, + ) + + class IgnoreAction(proto.Message): + r"""Prevents a term in the query from being used in search. + Example: Don't search for "shoddy". + + Attributes: + ignore_terms (MutableSequence[str]): + Terms to ignore in the search query. + """ + + ignore_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + boost_action: BoostAction = proto.Field( + proto.MESSAGE, + number=2, + oneof='action', + message=BoostAction, + ) + redirect_action: RedirectAction = proto.Field( + proto.MESSAGE, + number=3, + oneof='action', + message=RedirectAction, + ) + oneway_synonyms_action: OnewaySynonymsAction = proto.Field( + proto.MESSAGE, + number=6, + oneof='action', + message=OnewaySynonymsAction, + ) + do_not_associate_action: DoNotAssociateAction = proto.Field( + proto.MESSAGE, + number=7, + oneof='action', + message=DoNotAssociateAction, + ) + replacement_action: ReplacementAction = proto.Field( + proto.MESSAGE, + number=8, + oneof='action', + message=ReplacementAction, + ) + ignore_action: IgnoreAction = proto.Field( + proto.MESSAGE, + number=9, + oneof='action', + message=IgnoreAction, + ) + filter_action: FilterAction = proto.Field( + proto.MESSAGE, + number=10, + oneof='action', + message=FilterAction, + ) + twoway_synonyms_action: TwowaySynonymsAction = proto.Field( + proto.MESSAGE, + number=11, + oneof='action', + message=TwowaySynonymsAction, + ) + condition: 'Condition' = proto.Field( + proto.MESSAGE, + number=1, + message='Condition', + ) + + +class Audience(proto.Message): + r"""An intended audience of the + [Product][google.cloud.retail.v2.Product] for whom it's sold. + + Attributes: + genders (MutableSequence[str]): + The genders of the audience. Strongly encouraged to use the + standard values: "male", "female", "unisex". + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `gender `__. + Schema.org property + `Product.audience.suggestedGender `__. + age_groups (MutableSequence[str]): + The age groups of the audience. Strongly encouraged to use + the standard values: "newborn" (up to 3 months old), + "infant" (3–12 months old), "toddler" (1–5 years old), + "kids" (5–13 years old), "adult" (typically teens or older). + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `age_group `__. + Schema.org property + `Product.audience.suggestedMinAge `__ + and + `Product.audience.suggestedMaxAge `__. + """ + + genders: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + age_groups: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class ColorInfo(proto.Message): + r"""The color information of a + [Product][google.cloud.retail.v2.Product]. + + Attributes: + color_families (MutableSequence[str]): + The standard color families. Strongly recommended to use the + following standard color groups: "Red", "Pink", "Orange", + "Yellow", "Purple", "Green", "Cyan", "Blue", "Brown", + "White", "Gray", "Black" and "Mixed". Normally it is + expected to have only 1 color family. May consider using + single "Mixed" instead of multiple values. + + A maximum of 5 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + colors (MutableSequence[str]): + The color display names, which may be different from + standard color family names, such as the color aliases used + in the website frontend. Normally it is expected to have + only 1 color. May consider using single "Mixed" instead of + multiple values. + + A maximum of 75 colors are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + """ + + color_families: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + colors: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class CustomAttribute(proto.Message): + r"""A custom attribute that is not explicitly modeled in + [Product][google.cloud.retail.v2.Product]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text (MutableSequence[str]): + The textual values of this custom attribute. For example, + ``["yellow", "green"]`` when the key is "color". + + Empty string is not allowed. Otherwise, an INVALID_ARGUMENT + error is returned. + + Exactly one of + [text][google.cloud.retail.v2.CustomAttribute.text] or + [numbers][google.cloud.retail.v2.CustomAttribute.numbers] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. + numbers (MutableSequence[float]): + The numerical values of this custom attribute. For example, + ``[2.3, 15.4]`` when the key is "lengths_cm". + + Exactly one of + [text][google.cloud.retail.v2.CustomAttribute.text] or + [numbers][google.cloud.retail.v2.CustomAttribute.numbers] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. + searchable (bool): + This field is normally ignored unless + [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level] + of the [Catalog][google.cloud.retail.v2.Catalog] is set to + the deprecated 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For + information about product-level attribute configuration, see + `Configuration + modes `__. + If true, custom attribute values are searchable by text + queries in + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2.UserEvent]. + + Only set if type + [text][google.cloud.retail.v2.CustomAttribute.text] is set. + Otherwise, a INVALID_ARGUMENT error is returned. + + This field is a member of `oneof`_ ``_searchable``. + indexable (bool): + This field is normally ignored unless + [AttributesConfig.attribute_config_level][google.cloud.retail.v2.AttributesConfig.attribute_config_level] + of the [Catalog][google.cloud.retail.v2.Catalog] is set to + the deprecated 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For + information about product-level attribute configuration, see + `Configuration + modes `__. + If true, custom attribute values are indexed, so that they + can be filtered, faceted or boosted in + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2.UserEvent]. + + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter], + [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs] + and + [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec] + for more details. + + This field is a member of `oneof`_ ``_indexable``. + """ + + text: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + numbers: MutableSequence[float] = proto.RepeatedField( + proto.DOUBLE, + number=2, + ) + searchable: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + indexable: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) + + +class FulfillmentInfo(proto.Message): + r"""Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + Attributes: + type_ (str): + The fulfillment type, including commonly used types (such as + pickup in store and same day delivery), and custom types. + Customers have to map custom types to their display names + before rendering UI. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + place_ids (MutableSequence[str]): + The IDs for this + [type][google.cloud.retail.v2.FulfillmentInfo.type], such as + the store IDs for + [FulfillmentInfo.type.pickup-in-store][google.cloud.retail.v2.FulfillmentInfo.type] + or the region IDs for + [FulfillmentInfo.type.same-day-delivery][google.cloud.retail.v2.FulfillmentInfo.type]. + + A maximum of 3000 values are allowed. Each value must be a + string with a length limit of 30 characters, matching the + pattern ``[a-zA-Z0-9_-]+``, such as "store1" or "REGION-2". + Otherwise, an INVALID_ARGUMENT error is returned. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""[Product][google.cloud.retail.v2.Product] image. Recommendations AI + and Retail Search do not use product images to improve prediction + and search results. However, product images can be returned in + results, and are shown in prediction or search previews in the + console. + + Attributes: + uri (str): + Required. URI of the image. + + This field must be a valid UTF-8 encoded URI with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + height (int): + Height of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + width (int): + Width of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + height: int = proto.Field( + proto.INT32, + number=2, + ) + width: int = proto.Field( + proto.INT32, + number=3, + ) + + +class Interval(proto.Message): + r"""A floating point interval. + + 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: + minimum (float): + Inclusive lower bound. + + This field is a member of `oneof`_ ``min``. + exclusive_minimum (float): + Exclusive lower bound. + + This field is a member of `oneof`_ ``min``. + maximum (float): + Inclusive upper bound. + + This field is a member of `oneof`_ ``max``. + exclusive_maximum (float): + Exclusive upper bound. + + This field is a member of `oneof`_ ``max``. + """ + + minimum: float = proto.Field( + proto.DOUBLE, + number=1, + oneof='min', + ) + exclusive_minimum: float = proto.Field( + proto.DOUBLE, + number=2, + oneof='min', + ) + maximum: float = proto.Field( + proto.DOUBLE, + number=3, + oneof='max', + ) + exclusive_maximum: float = proto.Field( + proto.DOUBLE, + number=4, + oneof='max', + ) + + +class PriceInfo(proto.Message): + r"""The price information of a + [Product][google.cloud.retail.v2.Product]. + + Attributes: + currency_code (str): + The 3-letter currency code defined in `ISO + 4217 `__. + + If this field is an unrecognizable currency code, an + INVALID_ARGUMENT error is returned. + + The + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s with the same + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id] + must share the same + [currency_code][google.cloud.retail.v2.PriceInfo.currency_code]. + Otherwise, a FAILED_PRECONDITION error is returned. + price (float): + Price of the product. + + Google Merchant Center property + `price `__. + Schema.org property + `Offer.price `__. + original_price (float): + Price of the product without any discount. If zero, by + default set to be the + [price][google.cloud.retail.v2.PriceInfo.price]. If set, + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + should be greater than or equal to + [price][google.cloud.retail.v2.PriceInfo.price], otherwise + an INVALID_ARGUMENT error is thrown. + cost (float): + The costs associated with the sale of a particular product. + Used for gross profit reporting. + + - Profit = [price][google.cloud.retail.v2.PriceInfo.price] + - [cost][google.cloud.retail.v2.PriceInfo.cost] + + Google Merchant Center property + `cost_of_goods_sold `__. + price_effective_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2.PriceInfo.price] starts to be + effective. This can be set as a future timestamp, and the + [price][google.cloud.retail.v2.PriceInfo.price] is only used + for search after + [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time]. + If so, the + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + is used before + [price_effective_time][google.cloud.retail.v2.PriceInfo.price_effective_time]. + + Do not set if + [price][google.cloud.retail.v2.PriceInfo.price] is always + effective because it will cause additional latency during + search. + price_expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2.PriceInfo.price] stops to be + effective. The + [price][google.cloud.retail.v2.PriceInfo.price] is used for + search before + [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time]. + If this field is set, the + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2.PriceInfo.original_price] + is used after + [price_expire_time][google.cloud.retail.v2.PriceInfo.price_expire_time]. + + Do not set if + [price][google.cloud.retail.v2.PriceInfo.price] is always + effective because it will cause additional latency during + search. + price_range (google.cloud.retail_v2.types.PriceInfo.PriceRange): + Output only. The price range of all the child + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s grouped together + on the + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]. Only populated + for + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]. + Do not set this field in API requests. + """ + + class PriceRange(proto.Message): + r"""The price range of all + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] having the same + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. + + Attributes: + price (google.cloud.retail_v2.types.Interval): + The inclusive + [Product.pricing_info.price][google.cloud.retail.v2.PriceInfo.price] + interval of all + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] having the same + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. + original_price (google.cloud.retail_v2.types.Interval): + The inclusive + [Product.pricing_info.original_price][google.cloud.retail.v2.PriceInfo.original_price] + internal of all + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] having the same + [Product.primary_product_id][google.cloud.retail.v2.Product.primary_product_id]. + """ + + price: 'Interval' = proto.Field( + proto.MESSAGE, + number=1, + message='Interval', + ) + original_price: 'Interval' = proto.Field( + proto.MESSAGE, + number=2, + message='Interval', + ) + + currency_code: str = proto.Field( + proto.STRING, + number=1, + ) + price: float = proto.Field( + proto.FLOAT, + number=2, + ) + original_price: float = proto.Field( + proto.FLOAT, + number=3, + ) + cost: float = proto.Field( + proto.FLOAT, + number=4, + ) + price_effective_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + price_expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + price_range: PriceRange = proto.Field( + proto.MESSAGE, + number=7, + message=PriceRange, + ) + + +class Rating(proto.Message): + r"""The rating of a [Product][google.cloud.retail.v2.Product]. + + Attributes: + rating_count (int): + The total number of ratings. This value is independent of + the value of + [rating_histogram][google.cloud.retail.v2.Rating.rating_histogram]. + + This value must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + average_rating (float): + The average rating of the + [Product][google.cloud.retail.v2.Product]. + + The rating is scaled at 1-5. Otherwise, an INVALID_ARGUMENT + error is returned. + rating_histogram (MutableSequence[int]): + List of rating counts per rating value (index = rating - 1). + The list is empty if there is no rating. If the list is + non-empty, its size is always 5. Otherwise, an + INVALID_ARGUMENT error is returned. + + For example, [41, 14, 13, 47, 303]. It means that the + [Product][google.cloud.retail.v2.Product] got 41 ratings + with 1 star, 14 ratings with 2 star, and so on. + """ + + rating_count: int = proto.Field( + proto.INT32, + number=1, + ) + average_rating: float = proto.Field( + proto.FLOAT, + number=2, + ) + rating_histogram: MutableSequence[int] = proto.RepeatedField( + proto.INT32, + number=3, + ) + + +class UserInfo(proto.Message): + r"""Information of an end user. + + Attributes: + user_id (str): + Highly recommended for logged-in users. Unique identifier + for logged-in user, such as a user name. Don't set for + anonymous users. + + Always use a hashed value for this ID. + + Don't set the field to the same fixed ID for different + users. This mixes the event history of those users together, + which results in degraded model quality. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + ip_address (str): + The end user's IP address. This field is used to extract + location information for personalization. + + This field must be either an IPv4 address (e.g. + "104.133.9.80") or an IPv6 address (e.g. + "2001:0db8:85a3:0000:0000:8a2e:0370:7334"). Otherwise, an + INVALID_ARGUMENT error is returned. + + This should not be set when: + + - setting + [SearchRequest.user_info][google.cloud.retail.v2.SearchRequest.user_info]. + - using the JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent] + or if + [direct_user_request][google.cloud.retail.v2.UserInfo.direct_user_request] + is set. + user_agent (str): + User agent as included in the HTTP header. Required for + getting + [SearchResponse.sponsored_results][google.cloud.retail.v2.SearchResponse.sponsored_results]. + + The field must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This should not be set when using the client side event + reporting with GTM or JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent] + or if + [direct_user_request][google.cloud.retail.v2.UserInfo.direct_user_request] + is set. + direct_user_request (bool): + True if the request is made directly from the end user, in + which case the + [ip_address][google.cloud.retail.v2.UserInfo.ip_address] and + [user_agent][google.cloud.retail.v2.UserInfo.user_agent] can + be populated from the HTTP request. This flag should be set + only if the API request is made directly from the end user + such as a mobile app (and not if a gateway or a server is + processing and pushing the user events). + + This should not be set when using the JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2.UserEventService.CollectUserEvent]. + """ + + user_id: str = proto.Field( + proto.STRING, + number=1, + ) + ip_address: str = proto.Field( + proto.STRING, + number=2, + ) + user_agent: str = proto.Field( + proto.STRING, + number=3, + ) + direct_user_request: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class LocalInventory(proto.Message): + r"""The inventory information at a place (e.g. a store) + identified by a place ID. + + Attributes: + place_id (str): + The place ID for the current set of inventory + information. + price_info (google.cloud.retail_v2.types.PriceInfo): + Product price and cost information. + + Google Merchant Center property + `price `__. + attributes (MutableMapping[str, google.cloud.retail_v2.types.CustomAttribute]): + Additional local inventory attributes, for example, store + name, promotion tags, etc. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - At most 30 attributes are allowed. + - The key must be a UTF-8 encoded string with a length + limit of 32 characters. + - The key must match the pattern: + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, key0LikeThis + or KEY_1_LIKE_THIS. + - The attribute values must be of the same type (text or + number). + - Only 1 value is allowed for each attribute. + - For text values, the length limit is 256 UTF-8 + characters. + - The attribute does not support search. The ``searchable`` + field should be unset or set to false. + - The max summed total bytes of custom attribute keys and + values per product is 5MiB. + fulfillment_types (MutableSequence[str]): + Input only. Supported fulfillment types. Valid fulfillment + type values include commonly used types (such as pickup in + store and same day delivery), and custom types. Customers + have to map custom types to their display names before + rendering UI. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + All the elements must be distinct. Otherwise, an + INVALID_ARGUMENT error is returned. + """ + + place_id: str = proto.Field( + proto.STRING, + number=1, + ) + price_info: 'PriceInfo' = proto.Field( + proto.MESSAGE, + number=2, + message='PriceInfo', + ) + attributes: MutableMapping[str, 'CustomAttribute'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=3, + message='CustomAttribute', + ) + fulfillment_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py new file mode 100644 index 00000000..226562f7 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/completion_service.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import common + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'CompleteQueryRequest', + 'CompleteQueryResponse', + }, +) + + +class CompleteQueryRequest(proto.Message): + r"""Autocomplete parameters. + + Attributes: + catalog (str): + Required. Catalog for which the completion is performed. + + Full resource name of catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + query (str): + Required. The query used to generate + suggestions. + The maximum number of allowed characters is 255. + visitor_id (str): + Required field. A unique identifier for tracking visitors. + For example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor logs in or out of the website. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + language_codes (MutableSequence[str]): + Note that this field applies for ``user-data`` dataset only. + For requests with ``cloud-retail`` dataset, setting this + field has no effect. + + The language filters applied to the output suggestions. If + set, it should contain the language of the query. If not + set, suggestions are returned without considering language + restrictions. This is the BCP-47 language code, such as + "en-US" or "sr-Latn". For more information, see `Tags for + Identifying + Languages `__. The + maximum number of language codes is 3. + device_type (str): + The device type context for completion suggestions. We + recommend that you leave this field empty. + + It can apply different suggestions on different device + types, e.g. ``DESKTOP``, ``MOBILE``. If it is empty, the + suggestions are across all device types. + + Supported formats: + + - ``UNKNOWN_DEVICE_TYPE`` + + - ``DESKTOP`` + + - ``MOBILE`` + + - A customized string starts with ``OTHER_``, e.g. + ``OTHER_IPHONE``. + dataset (str): + Determines which dataset to use for fetching completion. + "user-data" will use the imported dataset through + [CompletionService.ImportCompletionData][google.cloud.retail.v2.CompletionService.ImportCompletionData]. + "cloud-retail" will use the dataset generated by cloud + retail based on user events. If leave empty, it will use the + "user-data". + + Current supported values: + + - user-data + + - cloud-retail: This option requires enabling auto-learning + function first. See + `guidelines `__. + max_suggestions (int): + Completion max suggestions. If left unset or set to 0, then + will fallback to the configured value + [CompletionConfig.max_suggestions][google.cloud.retail.v2.CompletionConfig.max_suggestions]. + + The maximum allowed max suggestions is 20. If it is set + higher, it will be capped by 20. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2.UserEvent.entity] + to get per-entity autocomplete results. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + query: str = proto.Field( + proto.STRING, + number=2, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=7, + ) + language_codes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + device_type: str = proto.Field( + proto.STRING, + number=4, + ) + dataset: str = proto.Field( + proto.STRING, + number=6, + ) + max_suggestions: int = proto.Field( + proto.INT32, + number=5, + ) + entity: str = proto.Field( + proto.STRING, + number=10, + ) + + +class CompleteQueryResponse(proto.Message): + r"""Response of the autocomplete query. + + Attributes: + completion_results (MutableSequence[google.cloud.retail_v2.types.CompleteQueryResponse.CompletionResult]): + Results of the matching suggestions. The + result list is ordered and the first result is + top suggestion. + attribution_token (str): + A unique complete token. This should be included in the + [UserEvent.completion_detail][google.cloud.retail.v2.UserEvent.completion_detail] + for search events resulting from this completion, which + enables accurate attribution of complete model performance. + recent_search_results (MutableSequence[google.cloud.retail_v2.types.CompleteQueryResponse.RecentSearchResult]): + Matched recent searches of this user. The maximum number of + recent searches is 10. This field is a restricted feature. + Contact Retail Search support team if you are interested in + enabling it. + + This feature is only available when + [CompleteQueryRequest.visitor_id][google.cloud.retail.v2.CompleteQueryRequest.visitor_id] + field is set and + [UserEvent][google.cloud.retail.v2.UserEvent] is imported. + The recent searches satisfy the follow rules: + + - They are ordered from latest to oldest. + + - They are matched with + [CompleteQueryRequest.query][google.cloud.retail.v2.CompleteQueryRequest.query] + case insensitively. + + - They are transformed to lower case. + + - They are UTF-8 safe. + + Recent searches are deduplicated. More recent searches will + be reserved when duplication happens. + """ + + class CompletionResult(proto.Message): + r"""Resource that represents completion results. + + Attributes: + suggestion (str): + The suggestion for the query. + attributes (MutableMapping[str, google.cloud.retail_v2.types.CustomAttribute]): + Custom attributes for the suggestion term. + + - For "user-data", the attributes are additional custom + attributes ingested through BigQuery. + + - For "cloud-retail", the attributes are product attributes + generated by Cloud Retail. It requires + [UserEvent.product_details][google.cloud.retail.v2.UserEvent.product_details] + is imported properly. + """ + + suggestion: str = proto.Field( + proto.STRING, + number=1, + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message=common.CustomAttribute, + ) + + class RecentSearchResult(proto.Message): + r"""Recent search of this user. + + Attributes: + recent_search (str): + The recent search query. + """ + + recent_search: str = proto.Field( + proto.STRING, + number=1, + ) + + completion_results: MutableSequence[CompletionResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=CompletionResult, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=2, + ) + recent_search_results: MutableSequence[RecentSearchResult] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=RecentSearchResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/control.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/control.py new file mode 100644 index 00000000..de570436 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/control.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 __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.retail_v2.types import common + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'Control', + }, +) + + +class Control(proto.Message): + r"""Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2.ServingConfig] and affect + search or recommendation results at serving time. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + rule (google.cloud.retail_v2.types.Rule): + A rule control - a condition-action pair. + Enacts a set action when the condition is + triggered. For example: Boost "gShoe" when query + full matches "Running Shoes". + + This field is a member of `oneof`_ ``control``. + name (str): + Immutable. Fully qualified name + ``projects/*/locations/global/catalogs/*/controls/*`` + display_name (str): + Required. The human readable control display name. Used in + Retail UI. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is thrown. + associated_serving_config_ids (MutableSequence[str]): + Output only. List of [serving + config][google.cloud.retail.v2.ServingConfig] ids that are + associated with this control in the same + [Catalog][google.cloud.retail.v2.Catalog]. + + Note the association is managed via the + [ServingConfig][google.cloud.retail.v2.ServingConfig], this + is an output only denormalized view. + solution_types (MutableSequence[google.cloud.retail_v2.types.SolutionType]): + Required. Immutable. The solution types that the control is + used for. Currently we support setting only one type of + solution at creation time. + + Only ``SOLUTION_TYPE_SEARCH`` value is supported at the + moment. If no solution type is provided at creation time, + will default to + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2.SolutionType.SOLUTION_TYPE_SEARCH]. + search_solution_use_case (MutableSequence[google.cloud.retail_v2.types.SearchSolutionUseCase]): + Specifies the use case for the control. Affects what + condition fields can be set. Only settable by search + controls. Will default to + [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + if not specified. Currently only allow one + search_solution_use_case per control. + """ + + rule: common.Rule = proto.Field( + proto.MESSAGE, + number=4, + oneof='control', + message=common.Rule, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + associated_serving_config_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + solution_types: MutableSequence[common.SolutionType] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=common.SolutionType, + ) + search_solution_use_case: MutableSequence[common.SearchSolutionUseCase] = proto.RepeatedField( + proto.ENUM, + number=7, + enum=common.SearchSolutionUseCase, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/control_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/control_service.py new file mode 100644 index 00000000..26939166 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/control_service.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 __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.retail_v2.types import control as gcr_control +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'CreateControlRequest', + 'UpdateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + }, +) + + +class CreateControlRequest(proto.Message): + r"""Request for CreateControl method. + + Attributes: + parent (str): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + control (google.cloud.retail_v2.types.Control): + Required. The Control to create. + control_id (str): + Required. The ID to use for the Control, which will become + the final component of the Control's resource name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-_/. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + control: gcr_control.Control = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_control.Control, + ) + control_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class UpdateControlRequest(proto.Message): + r"""Request for UpdateControl method. + + Attributes: + control (google.cloud.retail_v2.types.Control): + Required. The Control to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Control][google.cloud.retail.v2.Control] to update. The + following are NOT supported: + + - [Control.name][google.cloud.retail.v2.Control.name] + + If not set or empty, all supported fields are updated. + """ + + control: gcr_control.Control = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_control.Control, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteControlRequest(proto.Message): + r"""Request for DeleteControl method. + + Attributes: + name (str): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetControlRequest(proto.Message): + r"""Request for GetControl method. + + Attributes: + name (str): + Required. The resource name of the Control to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListControlsRequest(proto.Message): + r"""Request for ListControls method. + + Attributes: + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 50. Max + allowed value is 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListControls`` call. Provide this to retrieve the + subsequent page. + filter (str): + Optional. A filter to apply on the list results. Supported + features: + + - List all the products under the parent branch if + [filter][google.cloud.retail.v2.ListControlsRequest.filter] + is unset. + - List controls that are used in a single ServingConfig: + 'serving_config = "boosted_home_page_cvr"' + """ + + 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, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListControlsResponse(proto.Message): + r"""Response for ListControls method. + + Attributes: + controls (MutableSequence[google.cloud.retail_v2.types.Control]): + All the Controls for a given catalog. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + controls: MutableSequence[gcr_control.Control] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_control.Control, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py new file mode 100644 index 00000000..38318d8f --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/import_config.py @@ -0,0 +1,702 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import product +from google.cloud.retail_v2.types import user_event +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 google.type import date_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'GcsSource', + 'BigQuerySource', + 'ProductInlineSource', + 'UserEventInlineSource', + 'ImportErrorsConfig', + 'ImportProductsRequest', + 'ImportUserEventsRequest', + 'ImportCompletionDataRequest', + 'ProductInputConfig', + 'UserEventInputConfig', + 'CompletionDataInputConfig', + 'ImportMetadata', + 'ImportProductsResponse', + 'ImportUserEventsResponse', + 'UserEventImportSummary', + 'ImportCompletionDataResponse', + }, +) + + +class GcsSource(proto.Message): + r"""Google Cloud Storage location for input content. + + Attributes: + input_uris (MutableSequence[str]): + Required. Google Cloud Storage URIs to input files. URI can + be up to 2000 characters long. URIs can match the full + object path (for example, + ``gs://bucket/directory/object.json``) or a pattern matching + one or more files, such as ``gs://bucket/directory/*.json``. + A request can contain at most 100 files, and each file can + be up to 2 GB. See `Importing product + information `__ + for the expected file format and setup instructions. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2.Product] per line. Each + product must have a valid + [Product.id][google.cloud.retail.v2.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2.UserEvent] per line. + - ``user_event_ga360``: Using + https://support.google.com/analytics/answer/3437719. + + Supported values for control imports: + + - ``control`` (default): One JSON + [Control][google.cloud.retail.v2.Control] per line. + + Supported values for catalog attribute imports: + + - ``catalog_attribute`` (default): One CSV + [CatalogAttribute][google.cloud.retail.v2.CatalogAttribute] + per line. + """ + + input_uris: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + data_schema: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BigQuerySource(proto.Message): + r"""BigQuery source import data from. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + partition_date (google.type.date_pb2.Date): + BigQuery time partitioned table's \_PARTITIONDATE in + YYYY-MM-DD format. + + Only supported in + [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. + + This field is a member of `oneof`_ ``partition``. + project_id (str): + The project ID (can be project # or ID) that + the BigQuery source is in with a length limit of + 128 characters. If not specified, inherits the + project ID from the parent request. + dataset_id (str): + Required. The BigQuery data set to copy the + data from with a length limit of 1,024 + characters. + table_id (str): + Required. The BigQuery table to copy the data + from with a length limit of 1,024 characters. + gcs_staging_dir (str): + Intermediate Cloud Storage directory used for + the import with a length limit of 2,000 + characters. Can be specified if one wants to + have the BigQuery export to a specific Cloud + Storage directory. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2.Product] per line. Each + product must have a valid + [Product.id][google.cloud.retail.v2.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2.UserEvent] per line. + - ``user_event_ga360``: The schema is available here: + https://support.google.com/analytics/answer/3437719. + - ``user_event_ga4``: The schema is available here: + https://support.google.com/analytics/answer/7029846. + + Supported values for autocomplete imports: + + - ``suggestions`` (default): One JSON completion suggestion + per line. + - ``denylist``: One JSON deny suggestion per line. + - ``allowlist``: One JSON allow suggestion per line. + """ + + partition_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=6, + oneof='partition', + message=date_pb2.Date, + ) + project_id: str = proto.Field( + proto.STRING, + number=5, + ) + dataset_id: str = proto.Field( + proto.STRING, + number=1, + ) + table_id: str = proto.Field( + proto.STRING, + number=2, + ) + gcs_staging_dir: str = proto.Field( + proto.STRING, + number=3, + ) + data_schema: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ProductInlineSource(proto.Message): + r"""The inline source for the input config for ImportProducts + method. + + Attributes: + products (MutableSequence[google.cloud.retail_v2.types.Product]): + Required. A list of products to update/create. Each product + must have a valid + [Product.id][google.cloud.retail.v2.Product.id]. Recommended + max of 100 items. + """ + + products: MutableSequence[product.Product] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=product.Product, + ) + + +class UserEventInlineSource(proto.Message): + r"""The inline source for the input config for ImportUserEvents + method. + + Attributes: + user_events (MutableSequence[google.cloud.retail_v2.types.UserEvent]): + Required. A list of user events to import. + Recommended max of 10k items. + """ + + user_events: MutableSequence[user_event.UserEvent] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=user_event.UserEvent, + ) + + +class ImportErrorsConfig(proto.Message): + r"""Configuration of destination for Import related errors. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_prefix (str): + Google Cloud Storage prefix for import errors. This must be + an empty, existing Cloud Storage directory. Import errors + are written to sharded files in this directory, one per + line, as a JSON-encoded ``google.rpc.Status`` message. + + This field is a member of `oneof`_ ``destination``. + """ + + gcs_prefix: str = proto.Field( + proto.STRING, + number=1, + oneof='destination', + ) + + +class ImportProductsRequest(proto.Message): + r"""Request message for Import methods. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog/branches/default_branch`` + + If no updateMask is specified, requires products.create + permission. If updateMask is specified, requires + products.update permission. + request_id (str): + Deprecated. This field has no effect. + input_config (google.cloud.retail_v2.types.ProductInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided imported ``products`` + to update. If not set, all fields are updated. + reconciliation_mode (google.cloud.retail_v2.types.ImportProductsRequest.ReconciliationMode): + The mode of reconciliation between existing products and the + products to be imported. Defaults to + [ReconciliationMode.INCREMENTAL][google.cloud.retail.v2.ImportProductsRequest.ReconciliationMode.INCREMENTAL]. + notification_pubsub_topic (str): + Full Pub/Sub topic name for receiving notification. If this + field is set, when the import is finished, a notification is + sent to specified Pub/Sub topic. The message data is JSON + string of a [Operation][google.longrunning.Operation]. + + Format of the Pub/Sub topic is + ``projects/{project}/topics/{topic}``. It has to be within + the same project as + [ImportProductsRequest.parent][google.cloud.retail.v2.ImportProductsRequest.parent]. + Make sure that + ``service-@gcp-sa-retail.iam.gserviceaccount.com`` + has the ``pubsub.topics.publish`` IAM permission on the + topic. + """ + class ReconciliationMode(proto.Enum): + r"""Indicates how imported products are reconciled with the + existing products created or imported before. + + Values: + RECONCILIATION_MODE_UNSPECIFIED (0): + Defaults to INCREMENTAL. + INCREMENTAL (1): + Inserts new products or updates existing + products. + FULL (2): + Calculates diff and replaces the entire + product dataset. Existing products may be + deleted if they are not present in the source + location. + """ + RECONCILIATION_MODE_UNSPECIFIED = 0 + INCREMENTAL = 1 + FULL = 2 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + request_id: str = proto.Field( + proto.STRING, + number=6, + ) + input_config: 'ProductInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductInputConfig', + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=3, + message='ImportErrorsConfig', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + reconciliation_mode: ReconciliationMode = proto.Field( + proto.ENUM, + number=5, + enum=ReconciliationMode, + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=7, + ) + + +class ImportUserEventsRequest(proto.Message): + r"""Request message for the ImportUserEvents request. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog`` + input_config (google.cloud.retail_v2.types.UserEventInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. Cannot be set for inline user + event imports. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'UserEventInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='UserEventInputConfig', + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=3, + message='ImportErrorsConfig', + ) + + +class ImportCompletionDataRequest(proto.Message): + r"""Request message for ImportCompletionData methods. + + Attributes: + parent (str): + Required. The catalog which the suggestions dataset belongs + to. + + Format: + ``projects/1234/locations/global/catalogs/default_catalog``. + input_config (google.cloud.retail_v2.types.CompletionDataInputConfig): + Required. The desired input location of the + data. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'CompletionDataInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='CompletionDataInputConfig', + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ProductInputConfig(proto.Message): + r"""The input config source for products. + + 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_inline_source (google.cloud.retail_v2.types.ProductInlineSource): + The Inline source for the input content for + products. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2.types.GcsSource): + Google Cloud Storage location for the input + content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2.types.BigQuerySource): + BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + product_inline_source: 'ProductInlineSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='ProductInlineSource', + ) + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class UserEventInputConfig(proto.Message): + r"""The input config source for user events. + + 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: + user_event_inline_source (google.cloud.retail_v2.types.UserEventInlineSource): + Required. The Inline source for the input + content for UserEvents. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2.types.GcsSource): + Required. Google Cloud Storage location for + the input content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2.types.BigQuerySource): + Required. BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + user_event_inline_source: 'UserEventInlineSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='UserEventInlineSource', + ) + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class CompletionDataInputConfig(proto.Message): + r"""The input config source for completion data. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + big_query_source (google.cloud.retail_v2.types.BigQuerySource): + Required. BigQuery input source. + + Add the IAM permission "BigQuery Data Viewer" + for + cloud-retail-customer-data-access@system.gserviceaccount.com + before using this feature otherwise an error is + thrown. + + This field is a member of `oneof`_ ``source``. + """ + + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='BigQuerySource', + ) + + +class ImportMetadata(proto.Message): + r"""Metadata related to the progress of the Import operation. + This is returned by the google.longrunning.Operation.metadata + field. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + success_count (int): + Count of entries that were processed + successfully. + failure_count (int): + Count of entries that encountered errors + while processing. + request_id (str): + Deprecated. This field is never set. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + success_count: int = proto.Field( + proto.INT64, + number=3, + ) + failure_count: int = proto.Field( + proto.INT64, + number=4, + ) + request_id: str = proto.Field( + proto.STRING, + number=5, + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=6, + ) + + +class ImportProductsResponse(proto.Message): + r"""Response of the + [ImportProductsRequest][google.cloud.retail.v2.ImportProductsRequest]. + If the long running operation is done, then this message is returned + by the google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + Echoes the destination for the complete + errors in the request if set. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + + +class ImportUserEventsResponse(proto.Message): + r"""Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2.types.ImportErrorsConfig): + Echoes the destination for the complete + errors if this field was set in the request. + import_summary (google.cloud.retail_v2.types.UserEventImportSummary): + Aggregated statistics of user event import + status. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + import_summary: 'UserEventImportSummary' = proto.Field( + proto.MESSAGE, + number=3, + message='UserEventImportSummary', + ) + + +class UserEventImportSummary(proto.Message): + r"""A summary of import result. The UserEventImportSummary + summarizes the import status for user events. + + Attributes: + joined_events_count (int): + Count of user events imported with complete + existing catalog information. + unjoined_events_count (int): + Count of user events imported, but with + catalog information not found in the imported + catalog. + """ + + joined_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + unjoined_events_count: int = proto.Field( + proto.INT64, + number=2, + ) + + +class ImportCompletionDataResponse(proto.Message): + r"""Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2.ImportCompletionDataRequest]. + If the long running operation is done, this message is returned by + the google.longrunning.Operations.response field if the operation is + successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/model.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/model.py new file mode 100644 index 00000000..e51594f6 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/model.py @@ -0,0 +1,320 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import common +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'Model', + }, +) + + +class Model(proto.Message): + r"""Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2.Model]. A + [Model][google.cloud.retail.v2.Model] can be associated with a + [ServingConfig][google.cloud.retail.v2.ServingConfig] and then + queried through the Predict API. + + Attributes: + name (str): + Required. The fully qualified resource name of the model. + + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + catalog_id has char limit of 50. recommendation_model_id has + char limit of 40. + display_name (str): + Required. The display name of the model. + + Should be human readable, used to display + Recommendation Models in the Retail Cloud + Console Dashboard. UTF-8 encoded string with + limit of 1024 characters. + training_state (google.cloud.retail_v2.types.Model.TrainingState): + Optional. The training state that the model is in (e.g. + ``TRAINING`` or ``PAUSED``). + + Since part of the cost of running the service is frequency + of training - this can be used to determine when to train + model in order to control cost. If not specified: the + default value for ``CreateModel`` method is ``TRAINING``. + The default value for ``UpdateModel`` method is to keep the + state the same as before. + serving_state (google.cloud.retail_v2.types.Model.ServingState): + Output only. The serving state of the model: ``ACTIVE``, + ``NOT_ACTIVE``. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was created at. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was last updated. E.g. if a Recommendation + Model was paused - this would be the time the + pause was initiated. + type_ (str): + Required. The type of model e.g. ``home-page``. + + Currently supported values: ``recommended-for-you``, + ``others-you-may-like``, ``frequently-bought-together``, + ``page-optimization``, ``similar-items``, ``buy-it-again``, + ``on-sale-items``, and ``recently-viewed``\ (readonly + value). + + This field together with + [optimization_objective][google.cloud.retail.v2.Model.optimization_objective] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + optimization_objective (str): + Optional. The optimization objective e.g. ``cvr``. + + Currently supported values: ``ctr``, ``cvr``, + ``revenue-per-order``. + + If not specified, we choose default based on model type. + Default depends on type of recommendation: + + ``recommended-for-you`` => ``ctr`` + + ``others-you-may-like`` => ``ctr`` + + ``frequently-bought-together`` => ``revenue_per_order`` + + This field together with + [optimization_objective][google.cloud.retail.v2.Model.type] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + periodic_tuning_state (google.cloud.retail_v2.types.Model.PeriodicTuningState): + Optional. The state of periodic tuning. + + The period we use is 3 months - to do a one-off tune earlier + use the ``TuneModel`` method. Default value is + ``PERIODIC_TUNING_ENABLED``. + last_tune_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp when the latest + successful tune finished. + tuning_operation (str): + Output only. The tune operation associated + with the model. + Can be used to determine if there is an ongoing + tune for this recommendation. Empty field + implies no tune is goig on. + data_state (google.cloud.retail_v2.types.Model.DataState): + Output only. The state of data requirements for this model: + ``DATA_OK`` and ``DATA_ERROR``. + + Recommendation model cannot be trained if the data is in + ``DATA_ERROR`` state. Recommendation model can have + ``DATA_ERROR`` state even if serving state is ``ACTIVE``: + models were trained successfully before, but cannot be + refreshed because model no longer has sufficient data for + training. + filtering_option (google.cloud.retail_v2.types.RecommendationsFilteringOption): + Optional. If ``RECOMMENDATIONS_FILTERING_ENABLED``, + recommendation filtering by attributes is enabled for the + model. + serving_config_lists (MutableSequence[google.cloud.retail_v2.types.Model.ServingConfigList]): + Output only. The list of valid serving + configs associated with the + PageOptimizationConfig. + """ + class ServingState(proto.Enum): + r"""The serving state of the model. + + Values: + SERVING_STATE_UNSPECIFIED (0): + Unspecified serving state. + INACTIVE (1): + The model is not serving. + ACTIVE (2): + The model is serving and can be queried. + TUNED (3): + The model is trained on tuned hyperparameters + and can be queried. + """ + SERVING_STATE_UNSPECIFIED = 0 + INACTIVE = 1 + ACTIVE = 2 + TUNED = 3 + + class TrainingState(proto.Enum): + r"""The training state of the model. + + Values: + TRAINING_STATE_UNSPECIFIED (0): + Unspecified training state. + PAUSED (1): + The model training is paused. + TRAINING (2): + The model is training. + """ + TRAINING_STATE_UNSPECIFIED = 0 + PAUSED = 1 + TRAINING = 2 + + class PeriodicTuningState(proto.Enum): + r"""Describes whether periodic tuning is enabled for this model or not. + Periodic tuning is scheduled at most every three months. You can + start a tuning process manually by using the ``TuneModel`` method, + which starts a tuning process immediately and resets the quarterly + schedule. Enabling or disabling periodic tuning does not affect any + current tuning processes. + + Values: + PERIODIC_TUNING_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + PERIODIC_TUNING_DISABLED (1): + The model has periodic tuning disabled. Tuning can be + reenabled by calling the ``EnableModelPeriodicTuning`` + method or by calling the ``TuneModel`` method. + ALL_TUNING_DISABLED (3): + The model cannot be tuned with periodic tuning OR the + ``TuneModel`` method. Hide the options in customer UI and + reject any requests through the backend self serve API. + PERIODIC_TUNING_ENABLED (2): + The model has periodic tuning enabled. Tuning can be + disabled by calling the ``DisableModelPeriodicTuning`` + method. + """ + PERIODIC_TUNING_STATE_UNSPECIFIED = 0 + PERIODIC_TUNING_DISABLED = 1 + ALL_TUNING_DISABLED = 3 + PERIODIC_TUNING_ENABLED = 2 + + class DataState(proto.Enum): + r"""Describes whether this model have sufficient training data + to be continuously trained. + + Values: + DATA_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + DATA_OK (1): + The model has sufficient training data. + DATA_ERROR (2): + The model does not have sufficient training + data. Error messages can be queried via + Stackdriver. + """ + DATA_STATE_UNSPECIFIED = 0 + DATA_OK = 1 + DATA_ERROR = 2 + + class ServingConfigList(proto.Message): + r"""Represents an ordered combination of valid serving configs, which + can be used for ``PAGE_OPTIMIZATION`` recommendations. + + Attributes: + serving_config_ids (MutableSequence[str]): + Optional. A set of valid serving configs that may be used + for ``PAGE_OPTIMIZATION``. + """ + + serving_config_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + training_state: TrainingState = proto.Field( + proto.ENUM, + number=3, + enum=TrainingState, + ) + serving_state: ServingState = proto.Field( + proto.ENUM, + number=4, + enum=ServingState, + ) + 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, + ) + type_: str = proto.Field( + proto.STRING, + number=7, + ) + optimization_objective: str = proto.Field( + proto.STRING, + number=8, + ) + periodic_tuning_state: PeriodicTuningState = proto.Field( + proto.ENUM, + number=11, + enum=PeriodicTuningState, + ) + last_tune_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + tuning_operation: str = proto.Field( + proto.STRING, + number=15, + ) + data_state: DataState = proto.Field( + proto.ENUM, + number=16, + enum=DataState, + ) + filtering_option: common.RecommendationsFilteringOption = proto.Field( + proto.ENUM, + number=18, + enum=common.RecommendationsFilteringOption, + ) + serving_config_lists: MutableSequence[ServingConfigList] = proto.RepeatedField( + proto.MESSAGE, + number=19, + message=ServingConfigList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/model_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/model_service.py new file mode 100644 index 00000000..74657d17 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/model_service.py @@ -0,0 +1,274 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import model as gcr_model +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'CreateModelRequest', + 'UpdateModelRequest', + 'GetModelRequest', + 'PauseModelRequest', + 'ResumeModelRequest', + 'ListModelsRequest', + 'DeleteModelRequest', + 'ListModelsResponse', + 'TuneModelRequest', + 'CreateModelMetadata', + 'TuneModelMetadata', + 'TuneModelResponse', + }, +) + + +class CreateModelRequest(proto.Message): + r"""Request for creating a model. + + Attributes: + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + model (google.cloud.retail_v2.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2.Model] to create. + dry_run (bool): + Optional. Whether to run a dry run to + validate the request (without actually creating + the model). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_model.Model, + ) + dry_run: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class UpdateModelRequest(proto.Message): + r"""Request for updating an existing model. + + Attributes: + model (google.cloud.retail_v2.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2.Model]. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in the + provided 'model' to update. If not set, by + default updates all fields. + """ + + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetModelRequest(proto.Message): + r"""Request for getting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class PauseModelRequest(proto.Message): + r"""Request for pausing training of a model. + + Attributes: + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ResumeModelRequest(proto.Message): + r"""Request for resuming training of a model. + + Attributes: + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsRequest(proto.Message): + r"""Request for listing models associated with a resource. + + Attributes: + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 50. Max + allowed value is 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListModels`` call. Provide this to retrieve the subsequent + page. + """ + + 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 DeleteModelRequest(proto.Message): + r"""Request for deleting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsResponse(proto.Message): + r"""Response to a ListModelRequest. + + Attributes: + models (MutableSequence[google.cloud.retail_v2.types.Model]): + List of Models. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + models: MutableSequence[gcr_model.Model] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class TuneModelRequest(proto.Message): + r"""Request to manually start a tuning process now (instead of + waiting for the periodically scheduled tuning to happen). + + Attributes: + name (str): + Required. The resource name of the model to tune. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateModelMetadata(proto.Message): + r"""Metadata associated with a create operation. + + Attributes: + model (str): + The resource name of the model that this create applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelMetadata(proto.Message): + r"""Metadata associated with a tune operation. + + Attributes: + model (str): + The resource name of the model that this tune applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelResponse(proto.Message): + r"""Response associated with a tune operation. + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py new file mode 100644 index 00000000..50731b52 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/prediction_service.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import user_event as gcr_user_event +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'PredictRequest', + 'PredictResponse', + }, +) + + +class PredictRequest(proto.Message): + r"""Request message for Predict method. + + Attributes: + placement (str): + Required. Full resource name of the format: + ``{placement=projects/*/locations/global/catalogs/default_catalog/servingConfigs/*}`` + or + ``{placement=projects/*/locations/global/catalogs/default_catalog/placements/*}``. + We recommend using the ``servingConfigs`` resource. + ``placements`` is a legacy resource. The ID of the + Recommendations AI serving config or placement. Before you + can request predictions from your model, you must create at + least one serving config or placement for it. For more + information, see [Manage serving configs] + (https://cloud.google.com/retail/docs/manage-configs). + + The full list of available serving configs can be seen at + https://console.cloud.google.com/ai/retail/catalogs/default_catalog/configs + user_event (google.cloud.retail_v2.types.UserEvent): + Required. Context about the user, what they are looking at + and what action they took to trigger the predict request. + Note that this user event detail won't be ingested to + userEvent logs. Thus, a separate userEvent write request is + required for event logging. + + Don't set + [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id] + or + [UserInfo.user_id][google.cloud.retail.v2.UserInfo.user_id] + to the same fixed ID for different users. If you are trying + to receive non-personalized recommendations (not + recommended; this can negatively impact model performance), + instead set + [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id] + to a random unique ID and leave + [UserInfo.user_id][google.cloud.retail.v2.UserInfo.user_id] + unset. + page_size (int): + Maximum number of results to return. Set this + property to the number of prediction results + needed. If zero, the service will choose a + reasonable default. The maximum allowed value is + 100. Values above 100 will be coerced to 100. + page_token (str): + This field is not used; leave it unset. + filter (str): + Filter for restricting prediction results with a length + limit of 5,000 characters. Accepts values for tags and the + ``filterOutOfStockItems`` flag. + + - Tag expressions. Restricts predictions to products that + match all of the specified tags. Boolean operators ``OR`` + and ``NOT`` are supported if the expression is enclosed + in parentheses, and must be separated from the tag values + by a space. ``-"tagA"`` is also supported and is + equivalent to ``NOT "tagA"``. Tag values must be double + quoted UTF-8 encoded strings with a size limit of 1,000 + characters. + + Note: "Recently viewed" models don't support tag + filtering at the moment. + + - filterOutOfStockItems. Restricts predictions to products + that do not have a stockState value of OUT_OF_STOCK. + + Examples: + + - tag=("Red" OR "Blue") tag="New-Arrival" tag=(NOT + "promotional") + - filterOutOfStockItems tag=(-"promotional") + - filterOutOfStockItems + + If your filter blocks all prediction results, the API will + return *no* results. If instead you want empty result sets + to return generic (unfiltered) popular products, set + ``strictFiltering`` to False in ``PredictRequest.params``. + Note that the API will never return items with storageStatus + of "EXPIRED" or "DELETED" regardless of filter choices. + + If ``filterSyntaxV2`` is set to true under the ``params`` + field, then attribute-based expressions are expected instead + of the above described tag-based syntax. Examples: + + - (colors: ANY("Red", "Blue")) AND NOT (categories: + ANY("Phones")) + - (availability: ANY("IN_STOCK")) AND (colors: ANY("Red") + OR categories: ANY("Phones")) + + For more information, see `Filter + recommendations `__. + validate_only (bool): + Use validate only mode for this prediction + query. If set to true, a dummy model will be + used that returns arbitrary products. Note that + the validate only mode should only be used for + testing the API, or if the model is not ready. + params (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Additional domain specific parameters for the predictions. + + Allowed values: + + - ``returnProduct``: Boolean. If set to true, the + associated product object will be returned in the + ``results.metadata`` field in the prediction response. + - ``returnScore``: Boolean. If set to true, the prediction + 'score' corresponding to each returned product will be + set in the ``results.metadata`` field in the prediction + response. The given 'score' indicates the probability of + a product being clicked/purchased given the user's + context and history. + - ``strictFiltering``: Boolean. True by default. If set to + false, the service will return generic (unfiltered) + popular products instead of empty if your filter blocks + all prediction results. + - ``priceRerankLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of + {'no-price-reranking', 'low-price-reranking', + 'medium-price-reranking', 'high-price-reranking'}. This + gives request-level control and adjusts prediction + results based on product price. + - ``diversityLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of {'no-diversity', + 'low-diversity', 'medium-diversity', 'high-diversity', + 'auto-diversity'}. This gives request-level control and + adjusts prediction results based on product category. + - ``filterSyntaxV2``: Boolean. False by default. If set to + true, the ``filter`` field is interpreteted according to + the new, attribute-based syntax. + labels (MutableMapping[str, str]): + The labels applied to a resource must meet the following + requirements: + + - Each resource can have multiple labels, up to a maximum + of 64. + - Each label must be a key-value pair. + - Keys have a minimum length of 1 character and a maximum + length of 63 characters and cannot be empty. Values can + be empty and have a maximum length of 63 characters. + - Keys and values can contain only lowercase letters, + numeric characters, underscores, and dashes. All + characters must use UTF-8 encoding, and international + characters are allowed. + - The key portion of a label must be unique. However, you + can use the same key with multiple resources. + - Keys must start with a lowercase letter or international + character. + + See `Google Cloud + Document `__ + for more details. + """ + + placement: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: gcr_user_event.UserEvent = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + filter: str = proto.Field( + proto.STRING, + number=5, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=6, + ) + params: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=struct_pb2.Value, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=8, + ) + + +class PredictResponse(proto.Message): + r"""Response message for predict method. + + Attributes: + results (MutableSequence[google.cloud.retail_v2.types.PredictResponse.PredictionResult]): + A list of recommended products. The order + represents the ranking (from the most relevant + product to the least). + attribution_token (str): + A unique attribution token. This should be included in the + [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting + from this recommendation, which enables accurate attribution + of recommendation model performance. + missing_ids (MutableSequence[str]): + IDs of products in the request that were + missing from the inventory. + validate_only (bool): + True if the validateOnly property was set in + the request. + """ + + class PredictionResult(proto.Message): + r"""PredictionResult represents the recommendation prediction + results. + + Attributes: + id (str): + ID of the recommended product + metadata (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Additional product metadata / annotations. + + Possible values: + + - ``product``: JSON representation of the product. Is set + if ``returnProduct`` is set to true in + ``PredictRequest.params``. + - ``score``: Prediction score in double value. Is set if + ``returnScore`` is set to true in + ``PredictRequest.params``. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + metadata: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message=struct_pb2.Value, + ) + + results: MutableSequence[PredictionResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=PredictionResult, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=2, + ) + missing_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py new file mode 100644 index 00000000..4c9f6683 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/product.py @@ -0,0 +1,796 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import common +from google.cloud.retail_v2.types import promotion +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'Product', + }, +) + + +class Product(proto.Message): + r"""Product captures all metadata information of items to be + recommended or searched. + + 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: + expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this product becomes unavailable for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + Note that this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]. + In general, we suggest the users to delete the stale + products explicitly, instead of using this field to + determine staleness. + + If it is set, the [Product][google.cloud.retail.v2.Product] + is not available for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + after + [expire_time][google.cloud.retail.v2.Product.expire_time]. + However, the product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + [expire_time][google.cloud.retail.v2.Product.expire_time] + must be later than + [available_time][google.cloud.retail.v2.Product.available_time] + and + [publish_time][google.cloud.retail.v2.Product.publish_time], + otherwise an INVALID_ARGUMENT error is thrown. + + Corresponding properties: Google Merchant Center property + `expiration_date `__. + + This field is a member of `oneof`_ ``expiration``. + ttl (google.protobuf.duration_pb2.Duration): + Input only. The TTL (time to live) of the product. Note that + this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]. + In general, we suggest the users to delete the stale + products explicitly, instead of using this field to + determine staleness. + + If it is set, it must be a non-negative value, and + [expire_time][google.cloud.retail.v2.Product.expire_time] is + set as current timestamp plus + [ttl][google.cloud.retail.v2.Product.ttl]. The derived + [expire_time][google.cloud.retail.v2.Product.expire_time] is + returned in the output and + [ttl][google.cloud.retail.v2.Product.ttl] is left blank when + retrieving the [Product][google.cloud.retail.v2.Product]. + + If it is set, the product is not available for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + after current timestamp plus + [ttl][google.cloud.retail.v2.Product.ttl]. However, the + product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts]. + + This field is a member of `oneof`_ ``expiration``. + name (str): + Immutable. Full resource name of the product, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/product_id``. + id (str): + Immutable. [Product][google.cloud.retail.v2.Product] + identifier, which is the final component of + [name][google.cloud.retail.v2.Product.name]. For example, + this field is "id_1", if + [name][google.cloud.retail.v2.Product.name] is + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/id_1``. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `id `__. + Schema.org property + `Product.sku `__. + type_ (google.cloud.retail_v2.types.Product.Type): + Immutable. The type of the product. Default to + [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type] + if unset. + primary_product_id (str): + Variant group identifier. Must be an + [id][google.cloud.retail.v2.Product.id], with the same + parent branch with this product. Otherwise, an error is + thrown. + + For + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s, this field can + only be empty or set to the same value as + [id][google.cloud.retail.v2.Product.id]. + + For VARIANT [Product][google.cloud.retail.v2.Product]s, this + field cannot be empty. A maximum of 2,000 products are + allowed to share the same + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]. Otherwise, an + INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `item_group_id `__. + Schema.org property + `Product.inProductGroupWithID `__. + collection_member_ids (MutableSequence[str]): + The [id][google.cloud.retail.v2.Product.id] of the + collection members when + [type][google.cloud.retail.v2.Product.type] is + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]. + + Non-existent product ids are allowed. The + [type][google.cloud.retail.v2.Product.type] of the members + must be either + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + or + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + otherwise an INVALID_ARGUMENT error is thrown. Should not + set it for other types. A maximum of 1000 values are + allowed. Otherwise, an INVALID_ARGUMENT error is return. + gtin (str): + The Global Trade Item Number (GTIN) of the product. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + This field must be a Unigram. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `gtin `__. + Schema.org property + `Product.isbn `__, + `Product.gtin8 `__, + `Product.gtin12 `__, + `Product.gtin13 `__, or + `Product.gtin14 `__. + + If the value is not a valid GTIN, an INVALID_ARGUMENT error + is returned. + categories (MutableSequence[str]): + Product categories. This field is repeated for supporting + one product belonging to several parallel categories. + Strongly recommended using the full path for better search / + recommendation quality. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + For example, if a shoes product belongs to both ["Shoes & + Accessories" -> "Shoes"] and ["Sports & Fitness" -> + "Athletic Clothing" -> "Shoes"], it could be represented as: + + :: + + "categories": [ + "Shoes & Accessories > Shoes", + "Sports & Fitness > Athletic Clothing > Shoes" + ] + + Must be set for + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] otherwise an + INVALID_ARGUMENT error is returned. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2.Product]. Empty values are + not allowed. Each value must be a UTF-8 encoded string with + a length limit of 5,000 characters. Otherwise, an + INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `google_product_category `__. + Schema.org property [Product.category] + (https://schema.org/category). + title (str): + Required. Product title. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `title `__. + Schema.org property + `Product.name `__. + brands (MutableSequence[str]): + The brands of the product. + + A maximum of 30 brands are allowed. Each brand must be a + UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `brand `__. + Schema.org property + `Product.brand `__. + description (str): + Product description. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `description `__. + Schema.org property + `Product.description `__. + language_code (str): + Language of the title/description and other string + attributes. Use language tags defined by `BCP + 47 `__. + + For product prediction, this field is ignored and the model + automatically detects the text language. The + [Product][google.cloud.retail.v2.Product] can include text + in different languages, but duplicating + [Product][google.cloud.retail.v2.Product]s to provide text + in multiple languages can result in degraded model + performance. + + For product search this field is in use. It defaults to + "en-US" if unset. + attributes (MutableMapping[str, google.cloud.retail_v2.types.CustomAttribute]): + Highly encouraged. Extra product attributes to be included. + For example, for products, this could include the store + name, vendor, style, color, etc. These are very strong + signals for recommendation model, thus we highly recommend + providing the attributes here. + + Features that can take on one of a limited number of + possible values. Two types of features can be set are: + + Textual features. some examples would be the brand/maker of + a product, or country of a customer. Numerical features. + Some examples would be the height/weight of a product, or + age of a customer. + + For example: + ``{ "vendor": {"text": ["vendor123", "vendor456"]}, "lengths_cm": {"numbers":[2.3, 15.4]}, "heights_cm": {"numbers":[8.1, 6.4]} }``. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - Max entries count: 200. + - The key must be a UTF-8 encoded string with a length + limit of 128 characters. + - For indexable attribute, the key must match the pattern: + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, + ``key0LikeThis`` or ``KEY_1_LIKE_THIS``. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a + non-empty UTF-8 encoded string with a length limit of 256 + characters. + - For number attributes, at most 400 values are allowed. + tags (MutableSequence[str]): + Custom tags associated with the product. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2.Product]. This value must + be a UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This tag can be used for filtering recommendation results by + passing the tag as part of the + [PredictRequest.filter][google.cloud.retail.v2.PredictRequest.filter]. + + Corresponding properties: Google Merchant Center property + `custom_label_0–4 `__. + price_info (google.cloud.retail_v2.types.PriceInfo): + Product price and cost information. + + Corresponding properties: Google Merchant Center property + `price `__. + rating (google.cloud.retail_v2.types.Rating): + The rating of this product. + available_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this + [Product][google.cloud.retail.v2.Product] becomes available + for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + Note that this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]. + availability (google.cloud.retail_v2.types.Product.Availability): + The online availability of the + [Product][google.cloud.retail.v2.Product]. Default to + [Availability.IN_STOCK][google.cloud.retail.v2.Product.Availability.IN_STOCK]. + + Corresponding properties: Google Merchant Center property + `availability `__. + Schema.org property + `Offer.availability `__. + available_quantity (google.protobuf.wrappers_pb2.Int32Value): + The available quantity of the item. + fulfillment_info (MutableSequence[google.cloud.retail_v2.types.FulfillmentInfo]): + Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + All the elements must have distinct + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type]. + Otherwise, an INVALID_ARGUMENT error is returned. + uri (str): + Canonical URL directly linking to the product detail page. + + It is strongly recommended to provide a valid uri for the + product, otherwise the service performance could be + significantly degraded. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `link `__. + Schema.org property `Offer.url `__. + images (MutableSequence[google.cloud.retail_v2.types.Image]): + Product images for the product. We highly recommend putting + the main image first. + + A maximum of 300 images are allowed. + + Corresponding properties: Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + audience (google.cloud.retail_v2.types.Audience): + The target group associated with a given + audience (e.g. male, veterans, car owners, + musicians, etc.) of the product. + color_info (google.cloud.retail_v2.types.ColorInfo): + The color of the product. + + Corresponding properties: Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + sizes (MutableSequence[str]): + The size of the product. To represent different size systems + or size types, consider using this format: + [[[size_system:]size_type:]size_value]. + + For example, in "US:MENS:M", "US" represents size system; + "MENS" represents size type; "M" represents size value. In + "GIRLS:27", size system is empty; "GIRLS" represents size + type; "27" represents size value. In "32 inches", both size + system and size type are empty, while size value is "32 + inches". + + A maximum of 20 values are allowed per + [Product][google.cloud.retail.v2.Product]. Each value must + be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `size `__, + `size_type `__, + and + `size_system `__. + Schema.org property + `Product.size `__. + materials (MutableSequence[str]): + The material of the product. For example, "leather", + "wooden". + + A maximum of 20 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 200 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `material `__. + Schema.org property + `Product.material `__. + patterns (MutableSequence[str]): + The pattern or graphic print of the product. For example, + "striped", "polka dot", "paisley". + + A maximum of 20 values are allowed per + [Product][google.cloud.retail.v2.Product]. Each value must + be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `pattern `__. + Schema.org property + `Product.pattern `__. + conditions (MutableSequence[str]): + The condition of the product. Strongly encouraged to use the + standard values: "new", "refurbished", "used". + + A maximum of 1 value is allowed per + [Product][google.cloud.retail.v2.Product]. Each value must + be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `condition `__. + Schema.org property + `Offer.itemCondition `__. + promotions (MutableSequence[google.cloud.retail_v2.types.Promotion]): + The promotions applied to the product. A maximum of 10 + values are allowed per + [Product][google.cloud.retail.v2.Product]. Only + [Promotion.promotion_id][google.cloud.retail.v2.Promotion.promotion_id] + will be used, other fields will be ignored if set. + publish_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the product is published by the retailer + for the first time, which indicates the freshness of the + products. Note that this field is different from + [available_time][google.cloud.retail.v2.Product.available_time], + given it purely describes product freshness regardless of + when it is available on search and recommendation. + retrievable_fields (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the + [Product][google.cloud.retail.v2.Product]s are returned in + [SearchResponse][google.cloud.retail.v2.SearchResponse]. + + Supported fields for all + [type][google.cloud.retail.v2.Product.type]s: + + - [audience][google.cloud.retail.v2.Product.audience] + - [availability][google.cloud.retail.v2.Product.availability] + - [brands][google.cloud.retail.v2.Product.brands] + - [color_info][google.cloud.retail.v2.Product.color_info] + - [conditions][google.cloud.retail.v2.Product.conditions] + - [gtin][google.cloud.retail.v2.Product.gtin] + - [materials][google.cloud.retail.v2.Product.materials] + - [name][google.cloud.retail.v2.Product.name] + - [patterns][google.cloud.retail.v2.Product.patterns] + - [price_info][google.cloud.retail.v2.Product.price_info] + - [rating][google.cloud.retail.v2.Product.rating] + - [sizes][google.cloud.retail.v2.Product.sizes] + - [title][google.cloud.retail.v2.Product.title] + - [uri][google.cloud.retail.v2.Product.uri] + + Supported fields only for + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION]: + + - [categories][google.cloud.retail.v2.Product.categories] + - [description][google.cloud.retail.v2.Product.description] + - [images][google.cloud.retail.v2.Product.images] + + Supported fields only for + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT]: + + - Only the first image in + [images][google.cloud.retail.v2.Product.images] + + To mark + [attributes][google.cloud.retail.v2.Product.attributes] as + retrievable, include paths of the form "attributes.key" + where "key" is the key of a custom attribute, as specified + in [attributes][google.cloud.retail.v2.Product.attributes]. + + For + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION], + the following fields are always returned in + [SearchResponse][google.cloud.retail.v2.SearchResponse] by + default: + + - [name][google.cloud.retail.v2.Product.name] + + For + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT], + the following fields are always returned in by default: + + - [name][google.cloud.retail.v2.Product.name] + - [color_info][google.cloud.retail.v2.Product.color_info] + + The maximum number of paths is 30. Otherwise, an + INVALID_ARGUMENT error is returned. + + Note: Returning more fields in + [SearchResponse][google.cloud.retail.v2.SearchResponse] can + increase response payload size and serving latency. + + This field is deprecated. Use the retrievable site-wide + control instead. + variants (MutableSequence[google.cloud.retail_v2.types.Product]): + Output only. Product variants grouped together on primary + product which share similar product attributes. It's + automatically grouped by + [primary_product_id][google.cloud.retail.v2.Product.primary_product_id] + for all the product variants. Only populated for + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct]. + Do not set this field in API requests. + local_inventories (MutableSequence[google.cloud.retail_v2.types.LocalInventory]): + Output only. A list of local inventories specific to + different places. + + This field can be managed by + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + and + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + APIs if fine-grained, high-volume updates are necessary. + """ + class Type(proto.Enum): + r"""The type of this product. + + Values: + TYPE_UNSPECIFIED (0): + Default value. Default to + [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2.ProductLevelConfig.ingestion_product_type] + if unset. + PRIMARY (1): + The primary type. + + As the primary unit for predicting, indexing and search + serving, a + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] is grouped with + multiple + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s. + VARIANT (2): + The variant type. + + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s usually share + some common attributes on the same + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s, but they have + variant attributes like different colors, sizes and prices, + etc. + COLLECTION (3): + The collection type. Collection products are bundled + [Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]s or + [Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s that are sold + together, such as a jewelry set with necklaces, earrings and + rings, etc. + """ + TYPE_UNSPECIFIED = 0 + PRIMARY = 1 + VARIANT = 2 + COLLECTION = 3 + + class Availability(proto.Enum): + r"""Product availability. If this field is unspecified, the + product is assumed to be in stock. + + Values: + AVAILABILITY_UNSPECIFIED (0): + Default product availability. Default to + [Availability.IN_STOCK][google.cloud.retail.v2.Product.Availability.IN_STOCK] + if unset. + IN_STOCK (1): + Product in stock. + OUT_OF_STOCK (2): + Product out of stock. + PREORDER (3): + Product that is in pre-order state. + BACKORDER (4): + Product that is back-ordered (i.e. + temporarily out of stock). + """ + AVAILABILITY_UNSPECIFIED = 0 + IN_STOCK = 1 + OUT_OF_STOCK = 2 + PREORDER = 3 + BACKORDER = 4 + + expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=16, + oneof='expiration', + message=timestamp_pb2.Timestamp, + ) + ttl: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=17, + oneof='expiration', + message=duration_pb2.Duration, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + type_: Type = proto.Field( + proto.ENUM, + number=3, + enum=Type, + ) + primary_product_id: str = proto.Field( + proto.STRING, + number=4, + ) + collection_member_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + gtin: str = proto.Field( + proto.STRING, + number=6, + ) + categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + title: str = proto.Field( + proto.STRING, + number=8, + ) + brands: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + description: str = proto.Field( + proto.STRING, + number=10, + ) + language_code: str = proto.Field( + proto.STRING, + number=11, + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=12, + message=common.CustomAttribute, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + price_info: common.PriceInfo = proto.Field( + proto.MESSAGE, + number=14, + message=common.PriceInfo, + ) + rating: common.Rating = proto.Field( + proto.MESSAGE, + number=15, + message=common.Rating, + ) + available_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=18, + message=timestamp_pb2.Timestamp, + ) + availability: Availability = proto.Field( + proto.ENUM, + number=19, + enum=Availability, + ) + available_quantity: wrappers_pb2.Int32Value = proto.Field( + proto.MESSAGE, + number=20, + message=wrappers_pb2.Int32Value, + ) + fulfillment_info: MutableSequence[common.FulfillmentInfo] = proto.RepeatedField( + proto.MESSAGE, + number=21, + message=common.FulfillmentInfo, + ) + uri: str = proto.Field( + proto.STRING, + number=22, + ) + images: MutableSequence[common.Image] = proto.RepeatedField( + proto.MESSAGE, + number=23, + message=common.Image, + ) + audience: common.Audience = proto.Field( + proto.MESSAGE, + number=24, + message=common.Audience, + ) + color_info: common.ColorInfo = proto.Field( + proto.MESSAGE, + number=25, + message=common.ColorInfo, + ) + sizes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=26, + ) + materials: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=27, + ) + patterns: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=28, + ) + conditions: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=29, + ) + promotions: MutableSequence[promotion.Promotion] = proto.RepeatedField( + proto.MESSAGE, + number=34, + message=promotion.Promotion, + ) + publish_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=33, + message=timestamp_pb2.Timestamp, + ) + retrievable_fields: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=30, + message=field_mask_pb2.FieldMask, + ) + variants: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=31, + message='Product', + ) + local_inventories: MutableSequence[common.LocalInventory] = proto.RepeatedField( + proto.MESSAGE, + number=35, + message=common.LocalInventory, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.py new file mode 100644 index 00000000..c0f84350 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/product_service.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. +# +from __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import product as gcr_product +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'CreateProductRequest', + 'GetProductRequest', + 'UpdateProductRequest', + 'DeleteProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'SetInventoryRequest', + 'SetInventoryMetadata', + 'SetInventoryResponse', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesResponse', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesResponse', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesResponse', + }, +) + + +class CreateProductRequest(proto.Message): + r"""Request message for + [ProductService.CreateProduct][google.cloud.retail.v2.ProductService.CreateProduct] + method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + product (google.cloud.retail_v2.types.Product): + Required. The [Product][google.cloud.retail.v2.Product] to + create. + product_id (str): + Required. The ID to use for the + [Product][google.cloud.retail.v2.Product], which will become + the final component of the + [Product.name][google.cloud.retail.v2.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2.Product]s with the same + [parent][google.cloud.retail.v2.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + product_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetProductRequest(proto.Message): + r"""Request message for + [ProductService.GetProduct][google.cloud.retail.v2.ProductService.GetProduct] + method. + + Attributes: + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the requested [Product][google.cloud.retail.v2.Product] + does not exist, a NOT_FOUND error is returned. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductRequest(proto.Message): + r"""Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + method. + + Attributes: + product (google.cloud.retail_v2.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to update + does not exist and + [allow_missing][google.cloud.retail.v2.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Product][google.cloud.retail.v2.Product] to update. The + immutable and output only fields are NOT supported. If not + set, all supported fields (the fields that are neither + immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask path as + "attributes.${key_name}". If a key name is present in the + mask but not in the patching product from the request, this + key will be deleted after the update. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, a + new [Product][google.cloud.retail.v2.Product] will be + created. In this situation, ``update_mask`` is ignored. + """ + + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class DeleteProductRequest(proto.Message): + r"""Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2.ProductService.DeleteProduct] + method. + + Attributes: + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2.Product] to delete + does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2.Product] to delete can + neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] with more than one + [variants][google.cloud.retail.v2.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2.Product] will be deleted. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListProductsRequest(proto.Message): + r"""Request message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + + Attributes: + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list products + under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2.Product]s under this + branch, regardless of whether or not this branch exists, a + PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of [Product][google.cloud.retail.v2.Product]s + to return. If unspecified, defaults to 100. The maximum + allowed value is 1000. Values above 1000 will be coerced to + 1000. + + If this field is negative, an INVALID_ARGUMENT error is + returned. + page_token (str): + A page token + [ListProductsResponse.next_page_token][google.cloud.retail.v2.ListProductsResponse.next_page_token], + received from a previous + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + filter (str): + A filter to apply on the list results. Supported features: + + - List all the products under the parent branch if + [filter][google.cloud.retail.v2.ListProductsRequest.filter] + is unset. + - List + [Product.Type.VARIANT][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s sharing the + same + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product]. For example: + ``primary_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2.Product]s bundled + in a + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product]. For example: + ``collection_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2.Product]s with a + partibular type. For example: ``type = "PRIMARY"`` + ``type = "VARIANT"`` ``type = "COLLECTION"`` + + If the field is unrecognizable, an INVALID_ARGUMENT error is + returned. + + If the specified + [Product.Type.PRIMARY][google.cloud.retail.v2.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2.Product] or + [Product.Type.COLLECTION][google.cloud.retail.v2.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2.Product] does not exist, a + NOT_FOUND error is returned. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields of [Product][google.cloud.retail.v2.Product] to + return in the responses. If not set or empty, the following + fields are returned: + + - [Product.name][google.cloud.retail.v2.Product.name] + - [Product.id][google.cloud.retail.v2.Product.id] + - [Product.title][google.cloud.retail.v2.Product.title] + - [Product.uri][google.cloud.retail.v2.Product.uri] + - [Product.images][google.cloud.retail.v2.Product.images] + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.brands][google.cloud.retail.v2.Product.brands] + + If "*" is provided, all fields are returned. + [Product.name][google.cloud.retail.v2.Product.name] is + always returned no matter what mask is set. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + """ + + 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, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + read_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=5, + message=field_mask_pb2.FieldMask, + ) + + +class ListProductsResponse(proto.Message): + r"""Response message for + [ProductService.ListProducts][google.cloud.retail.v2.ProductService.ListProducts] + method. + + Attributes: + products (MutableSequence[google.cloud.retail_v2.types.Product]): + The [Product][google.cloud.retail.v2.Product]s. + next_page_token (str): + A token that can be sent as + [ListProductsRequest.page_token][google.cloud.retail.v2.ListProductsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence[gcr_product.Product] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class SetInventoryRequest(proto.Message): + r"""Request message for + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + method. + + Attributes: + inventory (google.cloud.retail_v2.types.Product): + Required. The inventory information to update. The allowable + fields to update are: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2.Product] named in + [Product.name][google.cloud.retail.v2.Product.name], + regardless of whether or not it exists, a PERMISSION_DENIED + error is returned. + + If the [Product][google.cloud.retail.v2.Product] to update + does not have existing inventory information, the provided + inventory information will be inserted. + + If the [Product][google.cloud.retail.v2.Product] to update + has existing inventory information, the provided inventory + information will be merged while respecting the last update + time for each inventory field, using the provided or default + value for + [SetInventoryRequest.set_time][google.cloud.retail.v2.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of fulfillment + types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + - Checks that only the desired fulfillment info types have + empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + + The last update time is recorded for the following inventory + fields: + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + - [Product.availability][google.cloud.retail.v2.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2.Product.fulfillment_info] + + If a full overwrite of inventory information while ignoring + timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2.ProductService.UpdateProduct] + should be invoked instead. + set_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2.Product] to update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the request is issued, used to + prevent out-of-order updates on inventory fields + with the last update time recorded. If not + provided, the internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] with name + [Product.name][google.cloud.retail.v2.Product.name] is not + found, the inventory update will still be processed and + retained for at most 1 day until the + [Product][google.cloud.retail.v2.Product] is created. If set + to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2.Product] is not found. + """ + + inventory: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + set_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + set_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class SetInventoryMetadata(proto.Message): + r"""Metadata related to the progress of the SetInventory operation. + Currently empty because there is no meaningful metadata populated + from the + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + method. + + """ + + +class SetInventoryResponse(proto.Message): + r"""Response of the SetInventoryRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2.ProductService.SetInventory] + method. + + """ + + +class AddFulfillmentPlacesRequest(proto.Message): + r"""Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + This field directly corresponds to + [Product.fulfillment_info.type][google.cloud.retail.v2.FulfillmentInfo.type]. + place_ids (MutableSequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery" to be added for this + [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type]. + Duplicate IDs will be automatically ignored. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + + If the total number of place IDs exceeds 2000 for this + [type][google.cloud.retail.v2.AddFulfillmentPlacesRequest.type] + after adding, then the update will be rejected. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, the + fulfillment information will still be processed and retained + for at most 1 day and processed once the + [Product][google.cloud.retail.v2.Product] is created. If set + to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + type_: str = proto.Field( + proto.STRING, + number=2, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + add_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class AddFulfillmentPlacesMetadata(proto.Message): + r"""Metadata related to the progress of the AddFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + method. + + """ + + +class AddFulfillmentPlacesResponse(proto.Message): + r"""Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2.ProductService.AddFulfillmentPlaces] + method. + + """ + + +class AddLocalInventoriesRequest(proto.Message): + r"""Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + local_inventories (MutableSequence[google.cloud.retail_v2.types.LocalInventory]): + Required. A list of inventory information at + difference places. Each place is identified by + its place ID. At most 3000 inventories are + allowed per request. + add_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided list of + [LocalInventory][google.cloud.retail.v2.LocalInventory] to + update. The field is updated to the provided value. + + If a field is set while the place does not have a previous + local inventory, the local inventory at that store is + created. + + If a field is set while the value of that field is not + provided, the original field value, if it exists, is + deleted. + + If the mask is not set or set with empty paths, all + inventory fields will be updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory updates are + issued. Used to prevent out-of-order updates on + local inventory fields. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, the + local inventory will still be processed and retained for at + most 1 day and processed once the + [Product][google.cloud.retail.v2.Product] is created. If set + to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + local_inventories: MutableSequence[common.LocalInventory] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.LocalInventory, + ) + add_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + add_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=6, + ) + + +class AddLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the AddLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method. + + """ + + +class AddLocalInventoriesResponse(proto.Message): + r"""Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful response + populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2.ProductService.AddLocalInventories] + method. + + """ + + +class RemoveLocalInventoriesRequest(proto.Message): + r"""Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + place_ids (MutableSequence[str]): + Required. A list of place IDs to have their + inventory deleted. At most 3000 place IDs are + allowed per request. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory deletions are + issued. Used to prevent out-of-order updates and + deletions on local inventory fields. If not + provided, the internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, the + local inventory removal request will still be processed and + retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2.Product] is created. If set + to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + remove_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class RemoveLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the RemoveLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method. + + """ + + +class RemoveLocalInventoriesResponse(proto.Message): + r"""Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful response + populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2.ProductService.RemoveLocalInventories] + method. + + """ + + +class RemoveFulfillmentPlacesRequest(proto.Message): + r"""Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + This field directly corresponds to + [Product.fulfillment_info.type][google.cloud.retail.v2.FulfillmentInfo.type]. + place_ids (MutableSequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery", to be removed for this + [type][google.cloud.retail.v2.RemoveFulfillmentPlacesRequest.type]. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2.Product] is not found, the + fulfillment information will still be processed and retained + for at most 1 day and processed once the + [Product][google.cloud.retail.v2.Product] is created. If set + to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + type_: str = proto.Field( + proto.STRING, + number=2, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + remove_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class RemoveFulfillmentPlacesMetadata(proto.Message): + r"""Metadata related to the progress of the RemoveFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + method. + + """ + + +class RemoveFulfillmentPlacesResponse(proto.Message): + r"""Response of the RemoveFulfillmentPlacesRequest. Currently empty + because there is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces] + method. + + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/promotion.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/promotion.py new file mode 100644 index 00000000..091d9cca --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/promotion.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail.v2', + manifest={ + 'Promotion', + }, +) + + +class Promotion(proto.Message): + r"""Promotion information. + + Attributes: + promotion_id (str): + ID of the promotion. For example, "free gift". + + The value must be a UTF-8 encoded string with a length limit + of 128 characters, and match the pattern: + ``[a-zA-Z][a-zA-Z0-9_]*``. For example, id0LikeThis or + ID_1_LIKE_THIS. Otherwise, an INVALID_ARGUMENT error is + returned. + + Google Merchant Center property + `promotion `__. + """ + + promotion_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py new file mode 100644 index 00000000..47399a9f --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/purge_config.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail.v2', + manifest={ + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + }, +) + + +class PurgeMetadata(proto.Message): + r"""Metadata related to the progress of the Purge operation. + This will be returned by the + google.longrunning.Operation.metadata field. + + """ + + +class PurgeUserEventsRequest(proto.Message): + r"""Request message for PurgeUserEvents method. + + Attributes: + parent (str): + Required. The resource name of the catalog under which the + events are created. The format is + ``projects/${projectId}/locations/global/catalogs/${catalogId}`` + filter (str): + Required. The filter string to specify the events to be + deleted with a length limit of 5,000 characters. Empty + string filter is not allowed. The eligible fields for + filtering are: + + - ``eventType``: Double quoted + [UserEvent.event_type][google.cloud.retail.v2.UserEvent.event_type] + string. + - ``eventTime``: in ISO 8601 "zulu" format. + - ``visitorId``: Double quoted string. Specifying this will + delete all events associated with a visitor. + - ``userId``: Double quoted string. Specifying this will + delete all events associated with a user. + + Examples: + + - Deleting all events in a time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventTime < "2012-04-23T18:30:43.511Z"`` + - Deleting specific eventType in time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventType = "detail-page-view"`` + - Deleting all events for a specific visitor: + ``visitorId = "visitor1024"`` + + The filtering fields are assumed to have an implicit AND. + force (bool): + Actually perform the purge. If ``force`` is set to false, + the method will return the expected purge count without + deleting any user events. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + force: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class PurgeUserEventsResponse(proto.Message): + r"""Response of the PurgeUserEventsRequest. If the long running + operation is successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + Attributes: + purged_events_count (int): + The total count of events purged as a result + of the operation. + """ + + purged_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py new file mode 100644 index 00000000..dc425712 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/search_service.py @@ -0,0 +1,1410 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import common +from google.cloud.retail_v2.types import product as gcr_product +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'SearchRequest', + 'SearchResponse', + 'ExperimentInfo', + }, +) + + +class SearchRequest(proto.Message): + r"""Request message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + placement (str): + Required. The resource name of the Retail Search serving + config, such as + ``projects/*/locations/global/catalogs/default_catalog/servingConfigs/default_serving_config`` + or the name of the legacy placement resource, such as + ``projects/*/locations/global/catalogs/default_catalog/placements/default_search``. + This field is used to identify the serving config name and + the set of models that will be used to make the search. + branch (str): + The branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + + Use "default_branch" as the branch ID or leave this field + empty, to search products under the default branch. + query (str): + Raw search query. + + If this field is empty, the request is considered a category + browsing request and returned results are based on + [filter][google.cloud.retail.v2.SearchRequest.filter] and + [page_categories][google.cloud.retail.v2.SearchRequest.page_categories]. + visitor_id (str): + Required. A unique identifier for tracking visitors. For + example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor logs in or out of the website. + + This should be the same identifier as + [UserEvent.visitor_id][google.cloud.retail.v2.UserEvent.visitor_id]. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + user_info (google.cloud.retail_v2.types.UserInfo): + User information. + page_size (int): + Maximum number of [Product][google.cloud.retail.v2.Product]s + to return. If unspecified, defaults to a reasonable value. + The maximum allowed value is 120. Values above 120 will be + coerced to 120. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [SearchResponse.next_page_token][google.cloud.retail.v2.SearchResponse.next_page_token], + received from a previous + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + offset (int): + A 0-indexed integer that specifies the current offset (that + is, starting result location, amongst the + [Product][google.cloud.retail.v2.Product]s deemed by the API + as relevant) in search results. This field is only + considered if + [page_token][google.cloud.retail.v2.SearchRequest.page_token] + is unset. + + If this field is negative, an INVALID_ARGUMENT is returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. Filter expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + canonical_filter (str): + The default filter that is applied when a user performs a + search without checking any filters on the search page. + + The filter applied to every search request when quality + improvement such as query expansion is needed. For example, + if a query does not have enough results, an expanded query + with + [SearchRequest.canonical_filter][google.cloud.retail.v2.SearchRequest.canonical_filter] + will be returned as a supplement of the original query. This + field is strongly recommended to achieve high search + quality. + + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for more details about filter syntax. + order_by (str): + The order in which products are returned. Products can be + ordered by a field in an + [Product][google.cloud.retail.v2.Product] object. Leave it + unset if ordered by relevance. OrderBy expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + facet_specs (MutableSequence[google.cloud.retail_v2.types.SearchRequest.FacetSpec]): + Facet specifications for faceted search. If empty, no facets + are returned. + + A maximum of 200 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + dynamic_facet_spec (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec): + Deprecated. Refer to + https://cloud.google.com/retail/docs/configs#dynamic + to enable dynamic facets. Do not set this field. + + The specification for dynamically generated + facets. Notice that only textual facets can be + dynamically generated. + boost_spec (google.cloud.retail_v2.types.SearchRequest.BoostSpec): + Boost specification to boost certain products. See more + details at this `user + guide `__. + + Notice that if both + [ServingConfig.boost_control_ids][google.cloud.retail.v2.ServingConfig.boost_control_ids] + and + [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec] + are set, the boost conditions from both places are + evaluated. If a search request matches multiple boost + conditions, the final boost score is equal to the sum of the + boost scores from all matched boost conditions. + query_expansion_spec (google.cloud.retail_v2.types.SearchRequest.QueryExpansionSpec): + The query expansion specification that specifies the + conditions under which query expansion will occur. See more + details at this `user + guide `__. + variant_rollup_keys (MutableSequence[str]): + The keys to fetch and rollup the matching + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s attributes, + [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo] or + [LocalInventory][google.cloud.retail.v2.LocalInventory]s + attributes. The attributes from all the matching + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s or + [LocalInventory][google.cloud.retail.v2.LocalInventory]s are + merged and de-duplicated. Notice that rollup attributes will + lead to extra query latency. Maximum number of keys is 30. + + For + [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], a + fulfillment type and a fulfillment ID must be provided in + the format of "fulfillmentType.fulfillmentId". E.g., in + "pickupInStore.store123", "pickupInStore" is fulfillment + type and "store123" is the store ID. + + Supported keys are: + + - colorFamilies + - price + - originalPrice + - discount + - variantId + - inventory(place_id,price) + - inventory(place_id,original_price) + - inventory(place_id,attributes.key), where key is any key + in the + [Product.local_inventories.attributes][google.cloud.retail.v2.LocalInventory.attributes] + map. + - attributes.key, where key is any key in the + [Product.attributes][google.cloud.retail.v2.Product.attributes] + map. + - pickupInStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "pickup-in-store". + - shipToStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "ship-to-store". + - sameDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "same-day-delivery". + - nextDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "next-day-delivery". + - customFulfillment1.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-1". + - customFulfillment2.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-2". + - customFulfillment3.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-3". + - customFulfillment4.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-4". + - customFulfillment5.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2.FulfillmentInfo.type] + "custom-type-5". + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + page_categories (MutableSequence[str]): + The categories associated with a category page. Required for + category navigation queries to achieve good search quality. + The format should be the same as + [UserEvent.page_categories][google.cloud.retail.v2.UserEvent.page_categories]; + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + search_mode (google.cloud.retail_v2.types.SearchRequest.SearchMode): + The search mode of the search request. If not + specified, a single search request triggers both + product search and faceted search. + personalization_spec (google.cloud.retail_v2.types.SearchRequest.PersonalizationSpec): + The specification for personalization. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec]. + labels (MutableMapping[str, str]): + The labels applied to a resource must meet the following + requirements: + + - Each resource can have multiple labels, up to a maximum + of 64. + - Each label must be a key-value pair. + - Keys have a minimum length of 1 character and a maximum + length of 63 characters and cannot be empty. Values can + be empty and have a maximum length of 63 characters. + - Keys and values can contain only lowercase letters, + numeric characters, underscores, and dashes. All + characters must use UTF-8 encoding, and international + characters are allowed. + - The key portion of a label must be unique. However, you + can use the same key with multiple resources. + - Keys must start with a lowercase letter or international + character. + + See `Google Cloud + Document `__ + for more details. + spell_correction_spec (google.cloud.retail_v2.types.SearchRequest.SpellCorrectionSpec): + The spell correction specification that + specifies the mode under which spell correction + will take effect. + + This field is a member of `oneof`_ ``_spell_correction_spec``. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2.UserEvent.entity] + to get search results boosted by entity. + """ + class SearchMode(proto.Enum): + r"""The search mode of each search request. + + Values: + SEARCH_MODE_UNSPECIFIED (0): + Default value. In this case both product search and faceted + search will be performed. Both + [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult] + and + [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet] + will be returned. + PRODUCT_SEARCH_ONLY (1): + Only product search will be performed. The faceted search + will be disabled. + + Only + [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult] + will be returned. + [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet] + will not be returned, even if + [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs] + or + [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2.SearchRequest.dynamic_facet_spec] + is set. + FACETED_SEARCH_ONLY (2): + Only faceted search will be performed. The product search + will be disabled. + + When in this mode, one or both of + [SearchRequest.facet_specs][google.cloud.retail.v2.SearchRequest.facet_specs] + and + [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2.SearchRequest.dynamic_facet_spec] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. Only + [SearchResponse.Facet][google.cloud.retail.v2.SearchResponse.Facet] + will be returned. + [SearchResponse.SearchResult][google.cloud.retail.v2.SearchResponse.SearchResult] + will not be returned. + """ + SEARCH_MODE_UNSPECIFIED = 0 + PRODUCT_SEARCH_ONLY = 1 + FACETED_SEARCH_ONLY = 2 + + class FacetSpec(proto.Message): + r"""A facet specification to perform faceted search. + + Attributes: + facet_key (google.cloud.retail_v2.types.SearchRequest.FacetSpec.FacetKey): + Required. The facet key specification. + limit (int): + Maximum of facet values that should be returned for this + facet. If unspecified, defaults to 50. The maximum allowed + value is 300. Values above 300 will be coerced to 300. + + If this field is negative, an INVALID_ARGUMENT is returned. + excluded_filter_keys (MutableSequence[str]): + List of keys to exclude when faceting. + + By default, + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + is not excluded from the filter unless it is listed in this + field. + + Listing a facet key in this field allows its values to + appear as facet results, even when they are filtered out of + search results. Using this field does not affect what search + results are returned. + + For example, suppose there are 100 products with the color + facet "Red" and 200 products with the color facet "Blue". A + query containing the filter "colorFamilies:ANY("Red")" and + having "colorFamilies" as + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + would by default return only "Red" products in the search + results, and also return "Red" with count 100 as the only + color facet. Although there are also blue products + available, "Blue" would not be shown as an available facet + value. + + If "colorFamilies" is listed in "excludedFilterKeys", then + the query returns the facet values "Red" with count 100 and + "Blue" with count 200, because the "colorFamilies" key is + now excluded from the filter. Because this field doesn't + affect search results, the search results are still + correctly filtered to return only "Red" products. + + A maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + enable_dynamic_position (bool): + Enables dynamic position for this facet. If set to true, the + position of this facet among all facets in the response is + determined by Google Retail Search. It will be ordered + together with dynamic facets if dynamic facets is enabled. + If set to false, the position of this facet in the response + will be the same as in the request, and it will be ranked + before the facets with dynamic position enable and all + dynamic facets. + + For example, you may always want to have rating facet + returned in the response, but it's not necessarily to always + display the rating facet at the top. In that case, you can + set enable_dynamic_position to true so that the position of + rating facet in response will be determined by Google Retail + Search. + + Another example, assuming you have the following facets in + the request: + + - "rating", enable_dynamic_position = true + + - "price", enable_dynamic_position = false + + - "brands", enable_dynamic_position = false + + And also you have a dynamic facets enable, which will + generate a facet 'gender'. Then the final order of the + facets in the response can be ("price", "brands", "rating", + "gender") or ("price", "brands", "gender", "rating") depends + on how Google Retail Search orders "gender" and "rating" + facets. However, notice that "price" and "brands" will + always be ranked at 1st and 2nd position since their + enable_dynamic_position are false. + """ + + class FacetKey(proto.Message): + r"""Specifies how a facet is computed. + + Attributes: + key (str): + Required. Supported textual and numerical facet keys in + [Product][google.cloud.retail.v2.Product] object, over which + the facet values are computed. Facet key is case-sensitive. + + Allowed facet keys when + [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query] + is not specified: + + - textual_field = + + - "brands" + - "categories" + - "genders" + - "ageGroups" + - "availability" + - "colorFamilies" + - "colors" + - "sizes" + - "materials" + - "patterns" + - "conditions" + - "attributes.key" + - "pickupInStore" + - "shipToStore" + - "sameDayDelivery" + - "nextDayDelivery" + - "customFulfillment1" + - "customFulfillment2" + - "customFulfillment3" + - "customFulfillment4" + - "customFulfillment5" + - "inventory(place_id,attributes.key)" + + - numerical_field = + + - "price" + - "discount" + - "rating" + - "ratingCount" + - "attributes.key" + - "inventory(place_id,price)" + - "inventory(place_id,original_price)" + - "inventory(place_id,attributes.key)". + intervals (MutableSequence[google.cloud.retail_v2.types.Interval]): + Set only if values should be bucketized into + intervals. Must be set for facets with numerical + values. Must not be set for facet with text + values. Maximum number of intervals is 40. + + For all numerical facet keys that appear in the + list of products from the catalog, the + percentiles 0, 10, 30, 50, 70, 90 and 100 are + computed from their distribution weekly. If the + model assigns a high score to a numerical facet + key and its intervals are not specified in the + search request, these percentiles will become + the bounds for its intervals and will be + returned in the response. If the facet key + intervals are specified in the request, then the + specified intervals will be returned instead. + restricted_values (MutableSequence[str]): + Only get facet for the given restricted values. For example, + when using "pickupInStore" as key and set restricted values + to ["store123", "store456"], only facets for "store123" and + "store456" are returned. Only supported on predefined + textual fields, custom textual attributes and fulfillments. + Maximum is 20. + + Must be set for the fulfillment facet keys: + + - pickupInStore + + - shipToStore + + - sameDayDelivery + + - nextDayDelivery + + - customFulfillment1 + + - customFulfillment2 + + - customFulfillment3 + + - customFulfillment4 + + - customFulfillment5 + prefixes (MutableSequence[str]): + Only get facet values that start with the + given string prefix. For example, suppose + "categories" has three values "Women > Shoe", + "Women > Dress" and "Men > Shoe". If set + "prefixes" to "Women", the "categories" facet + will give only "Women > Shoe" and "Women > + Dress". Only supported on textual fields. + Maximum is 10. + contains (MutableSequence[str]): + Only get facet values that contains the given + strings. For example, suppose "categories" has + three values "Women > Shoe", "Women > Dress" and + "Men > Shoe". If set "contains" to "Shoe", the + "categories" facet will give only "Women > Shoe" + and "Men > Shoe". Only supported on textual + fields. Maximum is 10. + case_insensitive (bool): + True to make facet keys case insensitive when + getting faceting values with prefixes or + contains; false otherwise. + order_by (str): + The order in which + [SearchResponse.Facet.values][google.cloud.retail.v2.SearchResponse.Facet.values] + are returned. + + Allowed values are: + + - "count desc", which means order by + [SearchResponse.Facet.values.count][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count] + descending. + + - "value desc", which means order by + [SearchResponse.Facet.values.value][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value] + descending. Only applies to textual facets. + + If not set, textual values are sorted in `natural + order `__; + numerical intervals are sorted in the order given by + [FacetSpec.FacetKey.intervals][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.intervals]; + [FulfillmentInfo.place_ids][google.cloud.retail.v2.FulfillmentInfo.place_ids] + are sorted in the order given by + [FacetSpec.FacetKey.restricted_values][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.restricted_values]. + query (str): + The query that is used to compute facet for the given facet + key. When provided, it will override the default behavior of + facet computation. The query syntax is the same as a filter + expression. See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for detail syntax and limitations. Notice that there is no + limitation on + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + when query is specified. + + In the response, + [SearchResponse.Facet.values.value][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.value] + will be always "1" and + [SearchResponse.Facet.values.count][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.count] + will be the number of results that match the query. + + For example, you can set a customized facet for + "shipToStore", where + [FacetKey.key][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.key] + is "customizedShipToStore", and + [FacetKey.query][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.query] + is "availability: ANY("IN_STOCK") AND shipToStore: + ANY("123")". Then the facet will count the products that are + both in stock and ship to store "123". + return_min_max (bool): + Returns the min and max value for each + numerical facet intervals. Ignored for textual + facets. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + intervals: MutableSequence[common.Interval] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.Interval, + ) + restricted_values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + prefixes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + contains: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + case_insensitive: bool = proto.Field( + proto.BOOL, + number=10, + ) + order_by: str = proto.Field( + proto.STRING, + number=4, + ) + query: str = proto.Field( + proto.STRING, + number=5, + ) + return_min_max: bool = proto.Field( + proto.BOOL, + number=11, + ) + + facet_key: 'SearchRequest.FacetSpec.FacetKey' = proto.Field( + proto.MESSAGE, + number=1, + message='SearchRequest.FacetSpec.FacetKey', + ) + limit: int = proto.Field( + proto.INT32, + number=2, + ) + excluded_filter_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + enable_dynamic_position: bool = proto.Field( + proto.BOOL, + number=4, + ) + + class DynamicFacetSpec(proto.Message): + r"""The specifications of dynamically generated facets. + + Attributes: + mode (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec.Mode): + Mode of the DynamicFacet feature. Defaults to + [Mode.DISABLED][google.cloud.retail.v2.SearchRequest.DynamicFacetSpec.Mode.DISABLED] + if it's unset. + """ + class Mode(proto.Enum): + r"""Enum to control DynamicFacet mode + + Values: + MODE_UNSPECIFIED (0): + Default value. + DISABLED (1): + Disable Dynamic Facet. + ENABLED (2): + Automatic mode built by Google Retail Search. + """ + MODE_UNSPECIFIED = 0 + DISABLED = 1 + ENABLED = 2 + + mode: 'SearchRequest.DynamicFacetSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.DynamicFacetSpec.Mode', + ) + + class BoostSpec(proto.Message): + r"""Boost specification to boost certain items. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + condition_boost_specs (MutableSequence[google.cloud.retail_v2.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + Condition boost specifications. If a product + matches multiple conditions in the + specifictions, boost scores from these + specifications are all applied and combined in a + non-linear way. Maximum number of specifications + is 20. + skip_boost_spec_validation (bool): + Whether to skip boostspec validation. If this field is set + to true, invalid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs] + will be ignored and valid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs] + will still be applied. + + This field is a member of `oneof`_ ``_skip_boost_spec_validation``. + """ + + class ConditionBoostSpec(proto.Message): + r"""Boost applies to products which match a condition. + + Attributes: + condition (str): + An expression which specifies a boost condition. The syntax + and supported fields are the same as a filter expression. + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for detail syntax and limitations. + + Examples: + + - To boost products with product ID "product_1" or + "product_2", and color "Red" or "Blue": + + - (id: ANY("product_1", "product_2")) AND + (colorFamilies: ANY("Red","Blue")) + boost (float): + Strength of the condition boost, which should be in [-1, 1]. + Negative boost means demotion. Default is 0.0. + + Setting to 1.0 gives the item a big promotion. However, it + does not necessarily mean that the boosted item will be the + top result at all times, nor that other items will be + excluded. Results could still be shown even when none of + them matches the condition. And results that are + significantly more relevant to the search query can still + trump your heavily favored but irrelevant items. + + Setting to -1.0 gives the item a big demotion. However, + results that are deeply relevant might still be shown. The + item will have an upstream battle to get a fairly high + ranking, but it is not blocked out completely. + + Setting to 0.0 means no boost applied. The boosting + condition is ignored. + """ + + condition: str = proto.Field( + proto.STRING, + number=1, + ) + boost: float = proto.Field( + proto.FLOAT, + number=2, + ) + + condition_boost_specs: MutableSequence['SearchRequest.BoostSpec.ConditionBoostSpec'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='SearchRequest.BoostSpec.ConditionBoostSpec', + ) + skip_boost_spec_validation: bool = proto.Field( + proto.BOOL, + number=2, + optional=True, + ) + + class QueryExpansionSpec(proto.Message): + r"""Specification to determine under which conditions query + expansion should occur. + + Attributes: + condition (google.cloud.retail_v2.types.SearchRequest.QueryExpansionSpec.Condition): + The condition under which query expansion should occur. + Default to + [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. + pin_unexpanded_results (bool): + Whether to pin unexpanded results. If this + field is set to true, unexpanded products are + always at the top of the search results, + followed by the expanded results. + """ + class Condition(proto.Enum): + r"""Enum describing under which condition query expansion should + occur. + + Values: + CONDITION_UNSPECIFIED (0): + Unspecified query expansion condition. In this case, server + behavior defaults to + [Condition.DISABLED][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. + DISABLED (1): + Disabled query expansion. Only the exact search query is + used, even if + [SearchResponse.total_size][google.cloud.retail.v2.SearchResponse.total_size] + is zero. + AUTO (3): + Automatic query expansion built by Google + Retail Search. + """ + CONDITION_UNSPECIFIED = 0 + DISABLED = 1 + AUTO = 3 + + condition: 'SearchRequest.QueryExpansionSpec.Condition' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.QueryExpansionSpec.Condition', + ) + pin_unexpanded_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class PersonalizationSpec(proto.Message): + r"""The specification for personalization. + + Attributes: + mode (google.cloud.retail_v2.types.SearchRequest.PersonalizationSpec.Mode): + Defaults to + [Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO]. + """ + class Mode(proto.Enum): + r"""The personalization mode of each search request. + + Values: + MODE_UNSPECIFIED (0): + Default value. In this case, server behavior defaults to + [Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO]. + AUTO (1): + Let CRS decide whether to use personalization + based on quality of user event data. + DISABLED (2): + Disable personalization. + """ + MODE_UNSPECIFIED = 0 + AUTO = 1 + DISABLED = 2 + + mode: 'SearchRequest.PersonalizationSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.PersonalizationSpec.Mode', + ) + + class SpellCorrectionSpec(proto.Message): + r"""The specification for query spell correction. + + Attributes: + mode (google.cloud.retail_v2.types.SearchRequest.SpellCorrectionSpec.Mode): + The mode under which spell correction should take effect to + replace the original search query. Default to + [Mode.AUTO][google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO]. + """ + class Mode(proto.Enum): + r"""Enum describing under which mode spell correction should + occur. + + Values: + MODE_UNSPECIFIED (0): + Unspecified spell correction mode. In this case, server + behavior defaults to + [Mode.AUTO][google.cloud.retail.v2.SearchRequest.SpellCorrectionSpec.Mode.AUTO]. + SUGGESTION_ONLY (1): + Google Retail Search will try to find a spell suggestion if + there is any and put in the + [SearchResponse.corrected_query][google.cloud.retail.v2.SearchResponse.corrected_query]. + The spell suggestion will not be used as the search query. + AUTO (2): + Automatic spell correction built by Google + Retail Search. Search will be based on the + corrected query if found. + """ + MODE_UNSPECIFIED = 0 + SUGGESTION_ONLY = 1 + AUTO = 2 + + mode: 'SearchRequest.SpellCorrectionSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.SpellCorrectionSpec.Mode', + ) + + placement: str = proto.Field( + proto.STRING, + number=1, + ) + branch: str = proto.Field( + proto.STRING, + number=2, + ) + query: str = proto.Field( + proto.STRING, + number=3, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=4, + ) + user_info: common.UserInfo = proto.Field( + proto.MESSAGE, + number=5, + message=common.UserInfo, + ) + page_size: int = proto.Field( + proto.INT32, + number=7, + ) + page_token: str = proto.Field( + proto.STRING, + number=8, + ) + offset: int = proto.Field( + proto.INT32, + number=9, + ) + filter: str = proto.Field( + proto.STRING, + number=10, + ) + canonical_filter: str = proto.Field( + proto.STRING, + number=28, + ) + order_by: str = proto.Field( + proto.STRING, + number=11, + ) + facet_specs: MutableSequence[FacetSpec] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message=FacetSpec, + ) + dynamic_facet_spec: DynamicFacetSpec = proto.Field( + proto.MESSAGE, + number=21, + message=DynamicFacetSpec, + ) + boost_spec: BoostSpec = proto.Field( + proto.MESSAGE, + number=13, + message=BoostSpec, + ) + query_expansion_spec: QueryExpansionSpec = proto.Field( + proto.MESSAGE, + number=14, + message=QueryExpansionSpec, + ) + variant_rollup_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=17, + ) + page_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=23, + ) + search_mode: SearchMode = proto.Field( + proto.ENUM, + number=31, + enum=SearchMode, + ) + personalization_spec: PersonalizationSpec = proto.Field( + proto.MESSAGE, + number=32, + message=PersonalizationSpec, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=34, + ) + spell_correction_spec: SpellCorrectionSpec = proto.Field( + proto.MESSAGE, + number=35, + optional=True, + message=SpellCorrectionSpec, + ) + entity: str = proto.Field( + proto.STRING, + number=38, + ) + + +class SearchResponse(proto.Message): + r"""Response message for + [SearchService.Search][google.cloud.retail.v2.SearchService.Search] + method. + + Attributes: + results (MutableSequence[google.cloud.retail_v2.types.SearchResponse.SearchResult]): + A list of matched items. The order represents + the ranking. + facets (MutableSequence[google.cloud.retail_v2.types.SearchResponse.Facet]): + Results of facets requested by user. + total_size (int): + The estimated total count of matched items irrespective of + pagination. The count of + [results][google.cloud.retail.v2.SearchResponse.results] + returned by pagination may be less than the + [total_size][google.cloud.retail.v2.SearchResponse.total_size] + that matches. + corrected_query (str): + Contains the spell corrected query, if found. If the spell + correction type is AUTOMATIC, then the search results are + based on corrected_query. Otherwise the original query is + used for search. + attribution_token (str): + A unique search token. This should be included in the + [UserEvent][google.cloud.retail.v2.UserEvent] logs resulting + from this search, which enables accurate attribution of + search model performance. + next_page_token (str): + A token that can be sent as + [SearchRequest.page_token][google.cloud.retail.v2.SearchRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + query_expansion_info (google.cloud.retail_v2.types.SearchResponse.QueryExpansionInfo): + Query expansion information for the returned + results. + redirect_uri (str): + The URI of a customer-defined redirect page. If redirect + action is triggered, no search is performed, and only + [redirect_uri][google.cloud.retail.v2.SearchResponse.redirect_uri] + and + [attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token] + are set in the response. + applied_controls (MutableSequence[str]): + The fully qualified resource name of applied + `controls `__. + invalid_condition_boost_specs (MutableSequence[google.cloud.retail_v2.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + The invalid + [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2.SearchRequest.BoostSpec.condition_boost_specs] + that are not applied during serving. + experiment_info (MutableSequence[google.cloud.retail_v2.types.ExperimentInfo]): + Metadata related to A/B testing [Experiment][] associated + with this response. Only exists when an experiment is + triggered. + """ + + class SearchResult(proto.Message): + r"""Represents the search results. + + Attributes: + id (str): + [Product.id][google.cloud.retail.v2.Product.id] of the + searched [Product][google.cloud.retail.v2.Product]. + product (google.cloud.retail_v2.types.Product): + The product data snippet in the search response. Only + [Product.name][google.cloud.retail.v2.Product.name] is + guaranteed to be populated. + + [Product.variants][google.cloud.retail.v2.Product.variants] + contains the product variants that match the search query. + If there are multiple product variants matching the query, + top 5 most relevant product variants are returned and + ordered by relevancy. + + If relevancy can be deternmined, use + [matching_variant_fields][google.cloud.retail.v2.SearchResponse.SearchResult.matching_variant_fields] + to look up matched product variants fields. If relevancy + cannot be determined, e.g. when searching "shoe" all + products in a shoe product can be a match, 5 product + variants are returned but order is meaningless. + matching_variant_count (int): + The count of matched + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product]s. + matching_variant_fields (MutableMapping[str, google.protobuf.field_mask_pb2.FieldMask]): + If a [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] matches the search + query, this map indicates which + [Product][google.cloud.retail.v2.Product] fields are + matched. The key is the + [Product.name][google.cloud.retail.v2.Product.name], the + value is a field mask of the matched + [Product][google.cloud.retail.v2.Product] fields. If matched + attributes cannot be determined, this map will be empty. + + For example, a key "sku1" with field mask + "products.color_info" indicates there is a match between + "sku1" [ColorInfo][google.cloud.retail.v2.ColorInfo] and the + query. + variant_rollup_values (MutableMapping[str, google.protobuf.struct_pb2.Value]): + The rollup matching + [variant][google.cloud.retail.v2.Product.Type.VARIANT] + [Product][google.cloud.retail.v2.Product] attributes. The + key is one of the + [SearchRequest.variant_rollup_keys][google.cloud.retail.v2.SearchRequest.variant_rollup_keys]. + The values are the merged and de-duplicated + [Product][google.cloud.retail.v2.Product] attributes. Notice + that the rollup values are respect filter. For example, when + filtering by "colorFamilies:ANY("red")" and rollup + "colorFamilies", only "red" is returned. + + For textual and numerical attributes, the rollup values is a + list of string or double values with type + [google.protobuf.ListValue][google.protobuf.ListValue]. For + example, if there are two variants with colors "red" and + "blue", the rollup values are + + :: + + { key: "colorFamilies" + value { + list_value { + values { string_value: "red" } + values { string_value: "blue" } + } + } + } + + For + [FulfillmentInfo][google.cloud.retail.v2.FulfillmentInfo], + the rollup values is a double value with type + [google.protobuf.Value][google.protobuf.Value]. For example, + ``{key: "pickupInStore.store1" value { number_value: 10 }}`` + means a there are 10 variants in this product are available + in the store "store1". + personal_labels (MutableSequence[str]): + Specifies previous events related to this product for this + user based on [UserEvent][google.cloud.retail.v2.UserEvent] + with same + [SearchRequest.visitor_id][google.cloud.retail.v2.SearchRequest.visitor_id] + or + [UserInfo.user_id][google.cloud.retail.v2.UserInfo.user_id]. + + This is set only when + [SearchRequest.PersonalizationSpec.mode][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.mode] + is + [SearchRequest.PersonalizationSpec.Mode.AUTO][google.cloud.retail.v2.SearchRequest.PersonalizationSpec.Mode.AUTO]. + + Possible values: + + - ``purchased``: Indicates that this product has been + purchased before. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + matching_variant_count: int = proto.Field( + proto.INT32, + number=3, + ) + matching_variant_fields: MutableMapping[str, field_mask_pb2.FieldMask] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + variant_rollup_values: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=5, + message=struct_pb2.Value, + ) + personal_labels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + + class Facet(proto.Message): + r"""A facet result. + + Attributes: + key (str): + The key for this facet. E.g., "colorFamilies" + or "price" or "attributes.attr1". + values (MutableSequence[google.cloud.retail_v2.types.SearchResponse.Facet.FacetValue]): + The facet values for this field. + dynamic_facet (bool): + Whether the facet is dynamically generated. + """ + + class FacetValue(proto.Message): + r"""A facet value which contains value names and their count. + + 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: + value (str): + Text value of a facet, such as "Black" for + facet "colorFamilies". + + This field is a member of `oneof`_ ``facet_value``. + interval (google.cloud.retail_v2.types.Interval): + Interval value for a facet, such as [10, 20) for facet + "price". + + This field is a member of `oneof`_ ``facet_value``. + count (int): + Number of items that have this facet value. + min_value (float): + The minimum value in the + [FacetValue.interval][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval]. + Only supported on numerical facets and returned if + [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max] + is true. + max_value (float): + The maximum value in the + [FacetValue.interval][google.cloud.retail.v2.SearchResponse.Facet.FacetValue.interval]. + Only supported on numerical facets and returned if + [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2.SearchRequest.FacetSpec.FacetKey.return_min_max] + is true. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + oneof='facet_value', + ) + interval: common.Interval = proto.Field( + proto.MESSAGE, + number=2, + oneof='facet_value', + message=common.Interval, + ) + count: int = proto.Field( + proto.INT64, + number=3, + ) + min_value: float = proto.Field( + proto.DOUBLE, + number=5, + ) + max_value: float = proto.Field( + proto.DOUBLE, + number=6, + ) + + key: str = proto.Field( + proto.STRING, + number=1, + ) + values: MutableSequence['SearchResponse.Facet.FacetValue'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='SearchResponse.Facet.FacetValue', + ) + dynamic_facet: bool = proto.Field( + proto.BOOL, + number=3, + ) + + class QueryExpansionInfo(proto.Message): + r"""Information describing query expansion including whether + expansion has occurred. + + Attributes: + expanded_query (bool): + Bool describing whether query expansion has + occurred. + pinned_result_count (int): + Number of pinned results. This field will only be set when + expansion happens and + [SearchRequest.QueryExpansionSpec.pin_unexpanded_results][google.cloud.retail.v2.SearchRequest.QueryExpansionSpec.pin_unexpanded_results] + is set to true. + """ + + expanded_query: bool = proto.Field( + proto.BOOL, + number=1, + ) + pinned_result_count: int = proto.Field( + proto.INT64, + number=2, + ) + + @property + def raw_page(self): + return self + + results: MutableSequence[SearchResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=SearchResult, + ) + facets: MutableSequence[Facet] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Facet, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + corrected_query: str = proto.Field( + proto.STRING, + number=4, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=5, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=6, + ) + query_expansion_info: QueryExpansionInfo = proto.Field( + proto.MESSAGE, + number=7, + message=QueryExpansionInfo, + ) + redirect_uri: str = proto.Field( + proto.STRING, + number=10, + ) + applied_controls: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + invalid_condition_boost_specs: MutableSequence['SearchRequest.BoostSpec.ConditionBoostSpec'] = proto.RepeatedField( + proto.MESSAGE, + number=14, + message='SearchRequest.BoostSpec.ConditionBoostSpec', + ) + experiment_info: MutableSequence['ExperimentInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=17, + message='ExperimentInfo', + ) + + +class ExperimentInfo(proto.Message): + r"""Metadata for active A/B testing [Experiments][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + serving_config_experiment (google.cloud.retail_v2.types.ExperimentInfo.ServingConfigExperiment): + A/B test between existing Cloud Retail Search + [ServingConfig][google.cloud.retail.v2.ServingConfig]s. + + This field is a member of `oneof`_ ``experiment_metadata``. + experiment (str): + The fully qualified resource name of the experiment that + provides the serving config under test, should an active + experiment exist. For example: + ``projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`` + """ + + class ServingConfigExperiment(proto.Message): + r"""Metadata for active serving config A/B tests. + + Attributes: + original_serving_config (str): + The fully qualified resource name of the original + [SearchRequest.placement][google.cloud.retail.v2.SearchRequest.placement] + in the search request prior to reassignment by experiment + API. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + experiment_serving_config (str): + The fully qualified resource name of the serving config + [VariantArm.serving_config_id][] responsible for generating + the search response. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + """ + + original_serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + experiment_serving_config: str = proto.Field( + proto.STRING, + number=2, + ) + + serving_config_experiment: ServingConfigExperiment = proto.Field( + proto.MESSAGE, + number=2, + oneof='experiment_metadata', + message=ServingConfigExperiment, + ) + experiment: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config.py new file mode 100644 index 00000000..f0f815a0 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config.py @@ -0,0 +1,357 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import common +from google.cloud.retail_v2.types import search_service + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'ServingConfig', + }, +) + + +class ServingConfig(proto.Message): + r"""Configures metadata that is used to generate serving time + results (e.g. search results or recommendation predictions). + + Attributes: + name (str): + Immutable. Fully qualified name + ``projects/*/locations/global/catalogs/*/servingConfig/*`` + display_name (str): + Required. The human readable serving config display name. + Used in Retail UI. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + model_id (str): + The id of the model in the same + [Catalog][google.cloud.retail.v2.Catalog] to use at serving + time. Currently only RecommendationModels are supported: + https://cloud.google.com/retail/recommendations-ai/docs/create-models + Can be changed but only to a compatible model (e.g. + others-you-may-like CTR to others-you-may-like CVR). + + Required when + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + price_reranking_level (str): + How much price ranking we want in serving results. Price + reranking causes product items with a similar recommendation + probability to be ordered by price, with the highest-priced + items first. This setting could result in a decrease in + click-through and conversion rates. Allowed values are: + + - ``no-price-reranking`` + - ``low-price-reranking`` + - ``medium-price-reranking`` + - ``high-price-reranking`` + + If not specified, we choose default based on model type. + Default value: ``no-price-reranking``. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + facet_control_ids (MutableSequence[str]): + Facet specifications for faceted search. If empty, no facets + are returned. The ids refer to the ids of + [Control][google.cloud.retail.v2.Control] resources with + only the Facet control set. These controls are assumed to be + in the same [Catalog][google.cloud.retail.v2.Catalog] as the + [ServingConfig][google.cloud.retail.v2.ServingConfig]. A + maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + dynamic_facet_spec (google.cloud.retail_v2.types.SearchRequest.DynamicFacetSpec): + The specification for dynamically generated facets. Notice + that only textual facets can be dynamically generated. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + boost_control_ids (MutableSequence[str]): + Condition boost specifications. If a product matches + multiple conditions in the specifications, boost scores from + these specifications are all applied and combined in a + non-linear way. Maximum number of specifications is 100. + + Notice that if both + [ServingConfig.boost_control_ids][google.cloud.retail.v2.ServingConfig.boost_control_ids] + and + [SearchRequest.boost_spec][google.cloud.retail.v2.SearchRequest.boost_spec] + are set, the boost conditions from both places are + evaluated. If a search request matches multiple boost + conditions, the final boost score is equal to the sum of the + boost scores from all matched boost conditions. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + filter_control_ids (MutableSequence[str]): + Condition filter specifications. If a product matches + multiple conditions in the specifications, filters from + these specifications are all applied and combined via the + AND operator. Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + redirect_control_ids (MutableSequence[str]): + Condition redirect specifications. Only the first triggered + redirect action is applied, even if multiple apply. Maximum + number of specifications is 1000. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + twoway_synonyms_control_ids (MutableSequence[str]): + Condition synonyms specifications. If multiple syonyms + conditions match, all matching synonyms control in the list + will execute. Order of controls in the list will not matter. + Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + oneway_synonyms_control_ids (MutableSequence[str]): + Condition oneway synonyms specifications. If multiple oneway + synonyms conditions match, all matching oneway synonyms + controls in the list will execute. Order of controls in the + list will not matter. Maximum number of specifications is + 100. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + do_not_associate_control_ids (MutableSequence[str]): + Condition do not associate specifications. If multiple do + not associate conditions match, all matching do not + associate controls in the list will execute. + + - Order does not matter. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + replacement_control_ids (MutableSequence[str]): + Condition replacement specifications. + + - Applied according to the order in the list. + - A previously replaced term can not be re-replaced. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + ignore_control_ids (MutableSequence[str]): + Condition ignore specifications. If multiple ignore + conditions match, all matching ignore controls in the list + will execute. + + - Order does not matter. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + diversity_level (str): + How much diversity to use in recommendation model results + e.g. ``medium-diversity`` or ``high-diversity``. Currently + supported values: + + - ``no-diversity`` + - ``low-diversity`` + - ``medium-diversity`` + - ``high-diversity`` + - ``auto-diversity`` + + If not specified, we choose default based on recommendation + model type. Default value: ``no-diversity``. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + diversity_type (google.cloud.retail_v2.types.ServingConfig.DiversityType): + What kind of diversity to use - data driven or rule based. + If unset, the server behavior defaults to + [RULE_BASED_DIVERSITY][google.cloud.retail.v2.ServingConfig.DiversityType.RULE_BASED_DIVERSITY]. + enable_category_filter_level (str): + Whether to add additional category filters on the + ``similar-items`` model. If not specified, we enable it by + default. Allowed values are: + + - ``no-category-match``: No additional filtering of + original results from the model and the customer's + filters. + - ``relaxed-category-match``: Only keep results with + categories that match at least one item categories in the + PredictRequests's context item. + + - If customer also sends filters in the PredictRequest, + then the results will satisfy both conditions (user + given and category match). + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + personalization_spec (google.cloud.retail_v2.types.SearchRequest.PersonalizationSpec): + The specification for personalization spec. + + Can only be set if + [solution_types][google.cloud.retail.v2.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2.ServingConfig.personalization_spec]. + solution_types (MutableSequence[google.cloud.retail_v2.types.SolutionType]): + Required. Immutable. Specifies the solution + types that a serving config can be associated + with. Currently we support setting only one type + of solution. + """ + class DiversityType(proto.Enum): + r"""What type of diversity - data or rule based. + + Values: + DIVERSITY_TYPE_UNSPECIFIED (0): + Default value. + RULE_BASED_DIVERSITY (2): + Rule based diversity. + DATA_DRIVEN_DIVERSITY (3): + Data driven diversity. + """ + DIVERSITY_TYPE_UNSPECIFIED = 0 + RULE_BASED_DIVERSITY = 2 + DATA_DRIVEN_DIVERSITY = 3 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + model_id: str = proto.Field( + proto.STRING, + number=3, + ) + price_reranking_level: str = proto.Field( + proto.STRING, + number=4, + ) + facet_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + dynamic_facet_spec: search_service.SearchRequest.DynamicFacetSpec = proto.Field( + proto.MESSAGE, + number=6, + message=search_service.SearchRequest.DynamicFacetSpec, + ) + boost_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + filter_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + redirect_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=10, + ) + twoway_synonyms_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=18, + ) + oneway_synonyms_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + do_not_associate_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + replacement_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=14, + ) + ignore_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=15, + ) + diversity_level: str = proto.Field( + proto.STRING, + number=8, + ) + diversity_type: DiversityType = proto.Field( + proto.ENUM, + number=20, + enum=DiversityType, + ) + enable_category_filter_level: str = proto.Field( + proto.STRING, + number=16, + ) + personalization_spec: search_service.SearchRequest.PersonalizationSpec = proto.Field( + proto.MESSAGE, + number=21, + message=search_service.SearchRequest.PersonalizationSpec, + ) + solution_types: MutableSequence[common.SolutionType] = proto.RepeatedField( + proto.ENUM, + number=19, + enum=common.SolutionType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config_service.py new file mode 100644 index 00000000..71b8c40f --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/serving_config_service.py @@ -0,0 +1,238 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import serving_config as gcr_serving_config +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'CreateServingConfigRequest', + 'UpdateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'AddControlRequest', + 'RemoveControlRequest', + }, +) + + +class CreateServingConfigRequest(proto.Message): + r"""Request for CreateServingConfig method. + + Attributes: + parent (str): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + serving_config (google.cloud.retail_v2.types.ServingConfig): + Required. The ServingConfig to create. + serving_config_id (str): + Required. The ID to use for the ServingConfig, which will + become the final component of the ServingConfig's resource + name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-_/. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + serving_config: gcr_serving_config.ServingConfig = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_serving_config.ServingConfig, + ) + serving_config_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class UpdateServingConfigRequest(proto.Message): + r"""Request for UpdateServingConfig method. + + Attributes: + serving_config (google.cloud.retail_v2.types.ServingConfig): + Required. The ServingConfig to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2.ServingConfig] to + update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2.ServingConfig.name] + + If not set, all supported fields are updated. + """ + + serving_config: gcr_serving_config.ServingConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_serving_config.ServingConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteServingConfigRequest(proto.Message): + r"""Request for DeleteServingConfig method. + + Attributes: + name (str): + Required. The resource name of the ServingConfig to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetServingConfigRequest(proto.Message): + r"""Request for GetServingConfig method. + + Attributes: + name (str): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListServingConfigsRequest(proto.Message): + r"""Request for ListServingConfigs method. + + Attributes: + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 100. If a + value greater than 100 is provided, at most 100 + results are returned. + page_token (str): + Optional. A page token, received from a previous + ``ListServingConfigs`` call. Provide this to retrieve the + subsequent page. + """ + + 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 ListServingConfigsResponse(proto.Message): + r"""Response for ListServingConfigs method. + + Attributes: + serving_configs (MutableSequence[google.cloud.retail_v2.types.ServingConfig]): + All the ServingConfigs for a given catalog. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + serving_configs: MutableSequence[gcr_serving_config.ServingConfig] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_serving_config.ServingConfig, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class AddControlRequest(proto.Message): + r"""Request for AddControl method. + + Attributes: + serving_config (str): + Required. The source ServingConfig resource name . Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + control_id (str): + Required. The id of the control to apply. Assumed to be in + the same catalog as the serving config - if id is not found + a NOT_FOUND error is returned. + """ + + serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + control_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RemoveControlRequest(proto.Message): + r"""Request for RemoveControl method. + + Attributes: + serving_config (str): + Required. The source ServingConfig resource name . Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + control_id (str): + Required. The id of the control to apply. + Assumed to be in the same catalog as the serving + config. + """ + + serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + control_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py new file mode 100644 index 00000000..dad97a1f --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event.py @@ -0,0 +1,524 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2.types import common +from google.cloud.retail_v2.types import product as gcr_product +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'UserEvent', + 'ProductDetail', + 'CompletionDetail', + 'PurchaseTransaction', + }, +) + + +class UserEvent(proto.Message): + r"""UserEvent captures all metadata information Retail API needs + to know about how end users interact with customers' website. + + Attributes: + event_type (str): + Required. User event type. Allowed values are: + + - ``add-to-cart``: Products being added to cart. + - ``category-page-view``: Special pages such as sale or + promotion pages viewed. + - ``detail-page-view``: Products detail page viewed. + - ``home-page-view``: Homepage viewed. + - ``promotion-offered``: Promotion is offered to a user. + - ``promotion-not-offered``: Promotion is not offered to a + user. + - ``purchase-complete``: User finishing a purchase. + - ``search``: Product search. + - ``shopping-cart-page-view``: User viewing a shopping + cart. + visitor_id (str): + Required. A unique identifier for tracking visitors. + + For example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor log in/out of the website. + + Don't set the field to the same fixed ID for different + users. This mixes the event history of those users together, + which results in degraded model quality. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + The field should not contain PII or user-data. We recommend + to use Google Analytics `Client + ID `__ + for this field. + session_id (str): + A unique identifier for tracking a visitor session with a + length limit of 128 bytes. A session is an aggregation of an + end user behavior in a time span. + + A general guideline to populate the sesion_id: + + 1. If user has no activity for 30 min, a new session_id + should be assigned. + 2. The session_id should be unique across users, suggest use + uuid or add visitor_id as prefix. + event_time (google.protobuf.timestamp_pb2.Timestamp): + Only required for + [UserEventService.ImportUserEvents][google.cloud.retail.v2.UserEventService.ImportUserEvents] + method. Timestamp of when the user event happened. + experiment_ids (MutableSequence[str]): + A list of identifiers for the independent + experiment groups this user event belongs to. + This is used to distinguish between user events + associated with different experiment setups + (e.g. using Retail API, using different + recommendation models). + attribution_token (str): + Highly recommended for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict]. + This field enables accurate attribution of recommendation + model performance. + + The value must be a valid + [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] + for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2.PredictionService.Predict]. + The value must be a valid + [SearchResponse.attribution_token][google.cloud.retail.v2.SearchResponse.attribution_token] + for user events that are the result of + [SearchService.Search][google.cloud.retail.v2.SearchService.Search]. + + This token enables us to accurately attribute page view or + purchase back to the event and the particular predict + response containing this clicked/purchased product. If user + clicks on product K in the recommendation results, pass + [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] + as a URL parameter to product K's page. When recording + events on product K's page, log the + [PredictResponse.attribution_token][google.cloud.retail.v2.PredictResponse.attribution_token] + to this field. + product_details (MutableSequence[google.cloud.retail_v2.types.ProductDetail]): + The main product details related to the event. + + This field is optional except for the following event types: + + - ``add-to-cart`` + - ``detail-page-view`` + - ``purchase-complete`` + + In a ``search`` event, this field represents the products + returned to the end user on the current page (the end user + may have not finished browsing the whole page yet). When a + new page is returned to the end user, after + pagination/filtering/ordering even for the same query, a new + ``search`` event with different + [product_details][google.cloud.retail.v2.UserEvent.product_details] + is desired. The end user may have not finished browsing the + whole page yet. + completion_detail (google.cloud.retail_v2.types.CompletionDetail): + The main auto-completion details related to the event. + + This field should be set for ``search`` event when + autocomplete function is enabled and the user clicks a + suggestion for search. + attributes (MutableMapping[str, google.cloud.retail_v2.types.CustomAttribute]): + Extra user event features to include in the recommendation + model. + + If you provide custom attributes for ingested user events, + also include them in the user events that you associate with + prediction requests. Custom attribute formatting must be + consistent between imported events and events provided with + prediction requests. This lets the Retail API use those + custom attributes when training models and serving + predictions, which helps improve recommendation quality. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - The key must be a UTF-8 encoded string with a length + limit of 5,000 characters. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a UTF-8 + encoded string with a length limit of 256 characters. + - For number attributes, at most 400 values are allowed. + + For product recommendations, an example of extra user + information is traffic_channel, which is how a user arrives + at the site. Users can arrive at the site by coming to the + site directly, coming through Google search, or in other + ways. + cart_id (str): + The ID or name of the associated shopping cart. This ID is + used to associate multiple items added or present in the + cart before purchase. + + This can only be set for ``add-to-cart``, + ``purchase-complete``, or ``shopping-cart-page-view`` + events. + purchase_transaction (google.cloud.retail_v2.types.PurchaseTransaction): + A transaction represents the entire purchase transaction. + + Required for ``purchase-complete`` events. Other event types + should not set this field. Otherwise, an INVALID_ARGUMENT + error is returned. + search_query (str): + The user's search query. + + See + [SearchRequest.query][google.cloud.retail.v2.SearchRequest.query] + for definition. + + The value must be a UTF-8 encoded string with a length limit + of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + At least one of + [search_query][google.cloud.retail.v2.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. + + See + [SearchRequest.filter][google.cloud.retail.v2.SearchRequest.filter] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + order_by (str): + The order in which products are returned. + + See + [SearchRequest.order_by][google.cloud.retail.v2.SearchRequest.order_by] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + offset (int): + An integer that specifies the current offset for pagination + (the 0-indexed starting location, amongst the products + deemed by the API as relevant). + + See + [SearchRequest.offset][google.cloud.retail.v2.SearchRequest.offset] + for definition. + + If this field is negative, an INVALID_ARGUMENT is returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + page_categories (MutableSequence[str]): + The categories associated with a category page. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + + Required for ``category-page-view`` events. At least one of + [search_query][google.cloud.retail.v2.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + user_info (google.cloud.retail_v2.types.UserInfo): + User information. + uri (str): + Complete URL (window.location.href) of the + user's current page. + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. Maximum length + 5,000 characters. + referrer_uri (str): + The referrer URL of the current page. + + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. + page_view_id (str): + A unique ID of a web page view. + + This should be kept the same for all user events triggered + from the same pageview. For example, an item detail page + view could trigger multiple events as the user is browsing + the page. The ``pageViewId`` property should be kept the + same for all these events so that they can be grouped + together properly. + + When using the client side event reporting with JavaScript + pixel and Google Tag Manager, this value is filled in + automatically. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. It is recommended to set this field to + get better per-entity search, completion and prediction + results. + """ + + event_type: str = proto.Field( + proto.STRING, + number=1, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=2, + ) + session_id: str = proto.Field( + proto.STRING, + number=21, + ) + event_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + experiment_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=5, + ) + product_details: MutableSequence['ProductDetail'] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message='ProductDetail', + ) + completion_detail: 'CompletionDetail' = proto.Field( + proto.MESSAGE, + number=22, + message='CompletionDetail', + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=common.CustomAttribute, + ) + cart_id: str = proto.Field( + proto.STRING, + number=8, + ) + purchase_transaction: 'PurchaseTransaction' = proto.Field( + proto.MESSAGE, + number=9, + message='PurchaseTransaction', + ) + search_query: str = proto.Field( + proto.STRING, + number=10, + ) + filter: str = proto.Field( + proto.STRING, + number=16, + ) + order_by: str = proto.Field( + proto.STRING, + number=17, + ) + offset: int = proto.Field( + proto.INT32, + number=18, + ) + page_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + user_info: common.UserInfo = proto.Field( + proto.MESSAGE, + number=12, + message=common.UserInfo, + ) + uri: str = proto.Field( + proto.STRING, + number=13, + ) + referrer_uri: str = proto.Field( + proto.STRING, + number=14, + ) + page_view_id: str = proto.Field( + proto.STRING, + number=15, + ) + entity: str = proto.Field( + proto.STRING, + number=23, + ) + + +class ProductDetail(proto.Message): + r"""Detailed product information associated with a user event. + + Attributes: + product (google.cloud.retail_v2.types.Product): + Required. [Product][google.cloud.retail.v2.Product] + information. + + Required field(s): + + - [Product.id][google.cloud.retail.v2.Product.id] + + Optional override field(s): + + - [Product.price_info][google.cloud.retail.v2.Product.price_info] + + If any supported optional fields are provided, we will treat + them as a full override when looking up product information + from the catalog. Thus, it is important to ensure that the + overriding fields are accurate and complete. + + All other product fields are ignored and instead populated + via catalog lookup after event ingestion. + quantity (google.protobuf.wrappers_pb2.Int32Value): + Quantity of the product associated with the user event. + + For example, this field will be 2 if two products are added + to the shopping cart for ``purchase-complete`` event. + Required for ``add-to-cart`` and ``purchase-complete`` event + types. + """ + + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + quantity: wrappers_pb2.Int32Value = proto.Field( + proto.MESSAGE, + number=2, + message=wrappers_pb2.Int32Value, + ) + + +class CompletionDetail(proto.Message): + r"""Detailed completion information including completion + attribution token and clicked completion info. + + Attributes: + completion_attribution_token (str): + Completion attribution token in + [CompleteQueryResponse.attribution_token][google.cloud.retail.v2.CompleteQueryResponse.attribution_token]. + selected_suggestion (str): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion]. + selected_position (int): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2.CompleteQueryResponse.CompletionResult.suggestion] + position, starting from 0. + """ + + completion_attribution_token: str = proto.Field( + proto.STRING, + number=1, + ) + selected_suggestion: str = proto.Field( + proto.STRING, + number=2, + ) + selected_position: int = proto.Field( + proto.INT32, + number=3, + ) + + +class PurchaseTransaction(proto.Message): + r"""A transaction represents the entire purchase transaction. + + Attributes: + id (str): + The transaction ID with a length limit of 128 + characters. + revenue (float): + Required. Total non-zero revenue or grand + total associated with the transaction. This + value include shipping, tax, or other + adjustments to total revenue that you want to + include as part of your revenue calculations. + tax (float): + All the taxes associated with the + transaction. + cost (float): + All the costs associated with the products. These can be + manufacturing costs, shipping expenses not borne by the end + user, or any other costs, such that: + + - Profit = + [revenue][google.cloud.retail.v2.PurchaseTransaction.revenue] + - [tax][google.cloud.retail.v2.PurchaseTransaction.tax] - + [cost][google.cloud.retail.v2.PurchaseTransaction.cost] + currency_code (str): + Required. Currency code. Use three-character + ISO-4217 code. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + revenue: float = proto.Field( + proto.FLOAT, + number=2, + ) + tax: float = proto.Field( + proto.FLOAT, + number=3, + ) + cost: float = proto.Field( + proto.FLOAT, + number=4, + ) + currency_code: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.py new file mode 100644 index 00000000..54420643 --- /dev/null +++ b/owl-bot-staging/v2/google/cloud/retail_v2/types/user_event_service.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 + +from google.cloud.retail_v2.types import user_event as gcr_user_event + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2', + manifest={ + 'WriteUserEventRequest', + 'CollectUserEventRequest', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'RejoinUserEventsMetadata', + }, +) + + +class WriteUserEventRequest(proto.Message): + r"""Request message for WriteUserEvent method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (google.cloud.retail_v2.types.UserEvent): + Required. User event to write. + write_async (bool): + If set to true, the user event will be + written asynchronously after validation, and the + API will respond without waiting for the write. + Therefore, silent failures can occur even if the + API returns success. In case of silent failures, + error messages can be found in Stackdriver logs. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: gcr_user_event.UserEvent = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) + write_async: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class CollectUserEventRequest(proto.Message): + r"""Request message for CollectUserEvent method. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + prebuilt_rule (str): + The prebuilt rule name that can convert a specific type of + raw_json. For example: "ga4_bq" rule for the GA4 user event + schema. + + This field is a member of `oneof`_ ``conversion_rule``. + parent (str): + Required. The parent catalog name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (str): + Required. URL encoded UserEvent proto with a + length limit of 2,000,000 characters. + uri (str): + The URL including cgi-parameters but + excluding the hash fragment with a length limit + of 5,000 characters. This is often more useful + than the referer URL, because many browsers only + send the domain for 3rd party requests. + ets (int): + The event timestamp in milliseconds. This + prevents browser caching of otherwise identical + get requests. The name is abbreviated to reduce + the payload bytes. + raw_json (str): + An arbitrary serialized JSON string that contains necessary + information that can comprise a user event. When this field + is specified, the user_event field will be ignored. Note: + line-delimited JSON is not supported, a single JSON only. + """ + + prebuilt_rule: str = proto.Field( + proto.STRING, + number=6, + oneof='conversion_rule', + ) + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: str = proto.Field( + proto.STRING, + number=2, + ) + uri: str = proto.Field( + proto.STRING, + number=3, + ) + ets: int = proto.Field( + proto.INT64, + number=4, + ) + raw_json: str = proto.Field( + proto.STRING, + number=5, + ) + + +class RejoinUserEventsRequest(proto.Message): + r"""Request message for RejoinUserEvents method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event_rejoin_scope (google.cloud.retail_v2.types.RejoinUserEventsRequest.UserEventRejoinScope): + The type of the user event rejoin to define the scope and + range of the user events to be rejoined with the latest + product catalog. Defaults to + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED`` if this field is not + set, or set to an invalid integer value. + """ + class UserEventRejoinScope(proto.Enum): + r"""The scope of user events to be rejoined with the latest product + catalog. If the rejoining aims at reducing number of unjoined + events, set ``UserEventRejoinScope`` to ``UNJOINED_EVENTS``. If the + rejoining aims at correcting product catalog information in joined + events, set ``UserEventRejoinScope`` to ``JOINED_EVENTS``. If all + events needs to be rejoined, set ``UserEventRejoinScope`` to + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED``. + + Values: + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED (0): + Rejoin all events with the latest product + catalog, including both joined events and + unjoined events. + JOINED_EVENTS (1): + Only rejoin joined events with the latest + product catalog. + UNJOINED_EVENTS (2): + Only rejoin unjoined events with the latest + product catalog. + """ + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED = 0 + JOINED_EVENTS = 1 + UNJOINED_EVENTS = 2 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event_rejoin_scope: UserEventRejoinScope = proto.Field( + proto.ENUM, + number=2, + enum=UserEventRejoinScope, + ) + + +class RejoinUserEventsResponse(proto.Message): + r"""Response message for ``RejoinUserEvents`` method. + + Attributes: + rejoined_user_events_count (int): + Number of user events that were joined with + latest product catalog. + """ + + rejoined_user_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + + +class RejoinUserEventsMetadata(proto.Message): + r"""Metadata for ``RejoinUserEvents`` method. + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2/mypy.ini b/owl-bot-staging/v2/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v2/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v2/noxfile.py b/owl-bot-staging/v2/noxfile.py new file mode 100644 index 00000000..c1fb7aa9 --- /dev/null +++ b/owl-bot-staging/v2/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/retail_v2/', + '--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/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_async.py new file mode 100644 index 00000000..8839c71d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_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 AddCatalogAttribute +# 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-retail + + +# [START retail_v2_generated_CatalogService_AddCatalogAttribute_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 retail_v2 + + +async def sample_add_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_AddCatalogAttribute_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_sync.py new file mode 100644 index 00000000..2a15edfd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_add_catalog_attribute_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 AddCatalogAttribute +# 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-retail + + +# [START retail_v2_generated_CatalogService_AddCatalogAttribute_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 retail_v2 + + +def sample_add_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_AddCatalogAttribute_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_async.py new file mode 100644 index 00000000..f2145df5 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_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 GetAttributesConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_GetAttributesConfig_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 retail_v2 + + +async def sample_get_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_GetAttributesConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_sync.py new file mode 100644 index 00000000..1095c8bd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_attributes_config_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 GetAttributesConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_GetAttributesConfig_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 retail_v2 + + +def sample_get_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_GetAttributesConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_async.py new file mode 100644 index 00000000..82c665ec --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_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 GetCompletionConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_GetCompletionConfig_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 retail_v2 + + +async def sample_get_completion_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_GetCompletionConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_sync.py new file mode 100644 index 00000000..b4d4a52e --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_completion_config_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 GetCompletionConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_GetCompletionConfig_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 retail_v2 + + +def sample_get_completion_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_GetCompletionConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_async.py new file mode 100644 index 00000000..c72ad228 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_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 GetDefaultBranch +# 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-retail + + +# [START retail_v2_generated_CatalogService_GetDefaultBranch_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 retail_v2 + + +async def sample_get_default_branch(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetDefaultBranchRequest( + ) + + # Make the request + response = await client.get_default_branch(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_GetDefaultBranch_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_sync.py new file mode 100644 index 00000000..a3a6455a --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_get_default_branch_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 GetDefaultBranch +# 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-retail + + +# [START retail_v2_generated_CatalogService_GetDefaultBranch_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 retail_v2 + + +def sample_get_default_branch(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetDefaultBranchRequest( + ) + + # Make the request + response = client.get_default_branch(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_GetDefaultBranch_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_async.py new file mode 100644 index 00000000..3185d971 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_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 ListCatalogs +# 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-retail + + +# [START retail_v2_generated_CatalogService_ListCatalogs_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 retail_v2 + + +async def sample_list_catalogs(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2_generated_CatalogService_ListCatalogs_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_sync.py new file mode 100644 index 00000000..52fb4b47 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_list_catalogs_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 ListCatalogs +# 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-retail + + +# [START retail_v2_generated_CatalogService_ListCatalogs_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 retail_v2 + + +def sample_list_catalogs(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2_generated_CatalogService_ListCatalogs_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_async.py new file mode 100644 index 00000000..5b0dae77 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_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 RemoveCatalogAttribute +# 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-retail + + +# [START retail_v2_generated_CatalogService_RemoveCatalogAttribute_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 retail_v2 + + +async def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = await client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_RemoveCatalogAttribute_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_sync.py new file mode 100644 index 00000000..c9efb423 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_remove_catalog_attribute_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 RemoveCatalogAttribute +# 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-retail + + +# [START retail_v2_generated_CatalogService_RemoveCatalogAttribute_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 retail_v2 + + +def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_RemoveCatalogAttribute_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_async.py new file mode 100644 index 00000000..442d6e60 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_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 ReplaceCatalogAttribute +# 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-retail + + +# [START retail_v2_generated_CatalogService_ReplaceCatalogAttribute_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 retail_v2 + + +async def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_ReplaceCatalogAttribute_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_sync.py new file mode 100644 index 00000000..1aaabb4f --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_replace_catalog_attribute_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 ReplaceCatalogAttribute +# 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-retail + + +# [START retail_v2_generated_CatalogService_ReplaceCatalogAttribute_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 retail_v2 + + +def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_ReplaceCatalogAttribute_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_async.py new file mode 100644 index 00000000..18c0383e --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_async.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetDefaultBranch +# 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-retail + + +# [START retail_v2_generated_CatalogService_SetDefaultBranch_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 retail_v2 + + +async def sample_set_default_branch(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.SetDefaultBranchRequest( + ) + + # Make the request + await client.set_default_branch(request=request) + + +# [END retail_v2_generated_CatalogService_SetDefaultBranch_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_sync.py new file mode 100644 index 00000000..8adc502d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_set_default_branch_sync.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetDefaultBranch +# 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-retail + + +# [START retail_v2_generated_CatalogService_SetDefaultBranch_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 retail_v2 + + +def sample_set_default_branch(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2.SetDefaultBranchRequest( + ) + + # Make the request + client.set_default_branch(request=request) + + +# [END retail_v2_generated_CatalogService_SetDefaultBranch_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_async.py new file mode 100644 index 00000000..c9778eef --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_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 UpdateAttributesConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_UpdateAttributesConfig_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 retail_v2 + + +async def sample_update_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + attributes_config = retail_v2.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = await client.update_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_UpdateAttributesConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_sync.py new file mode 100644 index 00000000..2f0224fa --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_attributes_config_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 UpdateAttributesConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_UpdateAttributesConfig_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 retail_v2 + + +def sample_update_attributes_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + attributes_config = retail_v2.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = client.update_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_UpdateAttributesConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_async.py new file mode 100644 index 00000000..e0b5f269 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_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 UpdateCatalog +# 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-retail + + +# [START retail_v2_generated_CatalogService_UpdateCatalog_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 retail_v2 + + +async def sample_update_catalog(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog = retail_v2.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = await client.update_catalog(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_UpdateCatalog_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_sync.py new file mode 100644 index 00000000..e16ca3e8 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_catalog_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 UpdateCatalog +# 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-retail + + +# [START retail_v2_generated_CatalogService_UpdateCatalog_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 retail_v2 + + +def sample_update_catalog(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + catalog = retail_v2.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = client.update_catalog(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_UpdateCatalog_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_async.py new file mode 100644 index 00000000..90428c19 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_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 UpdateCompletionConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_UpdateCompletionConfig_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 retail_v2 + + +async def sample_update_completion_config(): + # Create a client + client = retail_v2.CatalogServiceAsyncClient() + + # Initialize request argument(s) + completion_config = retail_v2.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = await client.update_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_UpdateCompletionConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_sync.py new file mode 100644 index 00000000..722381b4 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_catalog_service_update_completion_config_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 UpdateCompletionConfig +# 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-retail + + +# [START retail_v2_generated_CatalogService_UpdateCompletionConfig_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 retail_v2 + + +def sample_update_completion_config(): + # Create a client + client = retail_v2.CatalogServiceClient() + + # Initialize request argument(s) + completion_config = retail_v2.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = client.update_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CatalogService_UpdateCompletionConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_async.py new file mode 100644 index 00000000..7259abfd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_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 CompleteQuery +# 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-retail + + +# [START retail_v2_generated_CompletionService_CompleteQuery_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 retail_v2 + + +async def sample_complete_query(): + # Create a client + client = retail_v2.CompletionServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = await client.complete_query(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CompletionService_CompleteQuery_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_sync.py new file mode 100644 index 00000000..5efb4210 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_complete_query_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 CompleteQuery +# 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-retail + + +# [START retail_v2_generated_CompletionService_CompleteQuery_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 retail_v2 + + +def sample_complete_query(): + # Create a client + client = retail_v2.CompletionServiceClient() + + # Initialize request argument(s) + request = retail_v2.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = client.complete_query(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_CompletionService_CompleteQuery_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_async.py new file mode 100644 index 00000000..8e4cd7f4 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportCompletionData +# 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-retail + + +# [START retail_v2_generated_CompletionService_ImportCompletionData_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 retail_v2 + + +async def sample_import_completion_data(): + # Create a client + client = retail_v2.CompletionServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_CompletionService_ImportCompletionData_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_sync.py new file mode 100644 index 00000000..9d4b5723 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_completion_service_import_completion_data_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportCompletionData +# 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-retail + + +# [START retail_v2_generated_CompletionService_ImportCompletionData_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 retail_v2 + + +def sample_import_completion_data(): + # Create a client + client = retail_v2.CompletionServiceClient() + + # Initialize request argument(s) + input_config = retail_v2.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_CompletionService_ImportCompletionData_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_async.py new file mode 100644 index 00000000..13c4756a --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateControl +# 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-retail + + +# [START retail_v2_generated_ControlService_CreateControl_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 retail_v2 + + +async def sample_create_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = await client.create_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ControlService_CreateControl_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_sync.py new file mode 100644 index 00000000..ad71b96c --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_create_control_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateControl +# 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-retail + + +# [START retail_v2_generated_ControlService_CreateControl_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 retail_v2 + + +def sample_create_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = client.create_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ControlService_CreateControl_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_async.py new file mode 100644 index 00000000..2480fea6 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_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 DeleteControl +# 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-retail + + +# [START retail_v2_generated_ControlService_DeleteControl_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 retail_v2 + + +async def sample_delete_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteControlRequest( + name="name_value", + ) + + # Make the request + await client.delete_control(request=request) + + +# [END retail_v2_generated_ControlService_DeleteControl_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_sync.py new file mode 100644 index 00000000..543e8741 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_delete_control_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 DeleteControl +# 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-retail + + +# [START retail_v2_generated_ControlService_DeleteControl_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 retail_v2 + + +def sample_delete_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteControlRequest( + name="name_value", + ) + + # Make the request + client.delete_control(request=request) + + +# [END retail_v2_generated_ControlService_DeleteControl_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_async.py new file mode 100644 index 00000000..ff445c95 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_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 GetControl +# 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-retail + + +# [START retail_v2_generated_ControlService_GetControl_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 retail_v2 + + +async def sample_get_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetControlRequest( + name="name_value", + ) + + # Make the request + response = await client.get_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ControlService_GetControl_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_sync.py new file mode 100644 index 00000000..586676d0 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_get_control_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 GetControl +# 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-retail + + +# [START retail_v2_generated_ControlService_GetControl_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 retail_v2 + + +def sample_get_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetControlRequest( + name="name_value", + ) + + # Make the request + response = client.get_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ControlService_GetControl_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_async.py new file mode 100644 index 00000000..5312dea8 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_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 ListControls +# 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-retail + + +# [START retail_v2_generated_ControlService_ListControls_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 retail_v2 + + +async def sample_list_controls(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2_generated_ControlService_ListControls_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_sync.py new file mode 100644 index 00000000..513220b7 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_list_controls_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 ListControls +# 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-retail + + +# [START retail_v2_generated_ControlService_ListControls_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 retail_v2 + + +def sample_list_controls(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2_generated_ControlService_ListControls_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_async.py new file mode 100644 index 00000000..0955579d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_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 UpdateControl +# 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-retail + + +# [START retail_v2_generated_ControlService_UpdateControl_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 retail_v2 + + +async def sample_update_control(): + # Create a client + client = retail_v2.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateControlRequest( + control=control, + ) + + # Make the request + response = await client.update_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ControlService_UpdateControl_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_sync.py new file mode 100644 index 00000000..01d86829 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_control_service_update_control_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 UpdateControl +# 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-retail + + +# [START retail_v2_generated_ControlService_UpdateControl_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 retail_v2 + + +def sample_update_control(): + # Create a client + client = retail_v2.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2.Control() + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateControlRequest( + control=control, + ) + + # Make the request + response = client.update_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ControlService_UpdateControl_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_async.py new file mode 100644 index 00000000..34274ee5 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_async.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateModel +# 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-retail + + +# [START retail_v2_generated_ModelService_CreateModel_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 retail_v2 + + +async def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_CreateModel_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_sync.py new file mode 100644 index 00000000..e5bcb5fd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_create_model_sync.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateModel +# 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-retail + + +# [START retail_v2_generated_ModelService_CreateModel_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 retail_v2 + + +def sample_create_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_CreateModel_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_async.py new file mode 100644 index 00000000..03abcc0d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_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 DeleteModel +# 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-retail + + +# [START retail_v2_generated_ModelService_DeleteModel_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 retail_v2 + + +async def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + +# [END retail_v2_generated_ModelService_DeleteModel_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_sync.py new file mode 100644 index 00000000..d063d884 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_delete_model_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 DeleteModel +# 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-retail + + +# [START retail_v2_generated_ModelService_DeleteModel_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 retail_v2 + + +def sample_delete_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + +# [END retail_v2_generated_ModelService_DeleteModel_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_async.py new file mode 100644 index 00000000..621535d5 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_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 GetModel +# 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-retail + + +# [START retail_v2_generated_ModelService_GetModel_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 retail_v2 + + +async def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_GetModel_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_sync.py new file mode 100644 index 00000000..5b69c041 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_get_model_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 GetModel +# 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-retail + + +# [START retail_v2_generated_ModelService_GetModel_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 retail_v2 + + +def sample_get_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_GetModel_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_async.py new file mode 100644 index 00000000..541323fa --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_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 ListModels +# 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-retail + + +# [START retail_v2_generated_ModelService_ListModels_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 retail_v2 + + +async def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2_generated_ModelService_ListModels_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_sync.py new file mode 100644 index 00000000..2d649f24 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_list_models_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 ListModels +# 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-retail + + +# [START retail_v2_generated_ModelService_ListModels_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 retail_v2 + + +def sample_list_models(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2_generated_ModelService_ListModels_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_async.py new file mode 100644 index 00000000..2982e3af --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_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 PauseModel +# 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-retail + + +# [START retail_v2_generated_ModelService_PauseModel_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 retail_v2 + + +async def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_PauseModel_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_sync.py new file mode 100644 index 00000000..53250c14 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_pause_model_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 PauseModel +# 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-retail + + +# [START retail_v2_generated_ModelService_PauseModel_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 retail_v2 + + +def sample_pause_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_PauseModel_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_async.py new file mode 100644 index 00000000..8729b69a --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_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 ResumeModel +# 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-retail + + +# [START retail_v2_generated_ModelService_ResumeModel_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 retail_v2 + + +async def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_ResumeModel_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_sync.py new file mode 100644 index 00000000..bdacac08 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_resume_model_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 ResumeModel +# 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-retail + + +# [START retail_v2_generated_ModelService_ResumeModel_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 retail_v2 + + +def sample_resume_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_ResumeModel_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_async.py new file mode 100644 index 00000000..60974c7d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_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 TuneModel +# 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-retail + + +# [START retail_v2_generated_ModelService_TuneModel_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 retail_v2 + + +async def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_TuneModel_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_sync.py new file mode 100644 index 00000000..60278cb4 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_tune_model_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 TuneModel +# 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-retail + + +# [START retail_v2_generated_ModelService_TuneModel_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 retail_v2 + + +def sample_tune_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_TuneModel_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_async.py new file mode 100644 index 00000000..e8e2632e --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateModel +# 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-retail + + +# [START retail_v2_generated_ModelService_UpdateModel_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 retail_v2 + + +async def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_UpdateModel_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_sync.py new file mode 100644 index 00000000..b8c4f32f --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_model_service_update_model_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateModel +# 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-retail + + +# [START retail_v2_generated_ModelService_UpdateModel_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 retail_v2 + + +def sample_update_model(): + # Create a client + client = retail_v2.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ModelService_UpdateModel_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_async.py new file mode 100644 index 00000000..102c6d11 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Predict +# 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-retail + + +# [START retail_v2_generated_PredictionService_Predict_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 retail_v2 + + +async def sample_predict(): + # Create a client + client = retail_v2.PredictionServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = await client.predict(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_PredictionService_Predict_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_sync.py new file mode 100644 index 00000000..fd0f8418 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_prediction_service_predict_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Predict +# 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-retail + + +# [START retail_v2_generated_PredictionService_Predict_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 retail_v2 + + +def sample_predict(): + # Create a client + client = retail_v2.PredictionServiceClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = client.predict(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_PredictionService_Predict_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_async.py new file mode 100644 index 00000000..dcde873c --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 AddFulfillmentPlaces +# 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-retail + + +# [START retail_v2_generated_ProductService_AddFulfillmentPlaces_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 retail_v2 + + +async def sample_add_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_AddFulfillmentPlaces_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_sync.py new file mode 100644 index 00000000..5c4f64bd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_fulfillment_places_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 AddFulfillmentPlaces +# 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-retail + + +# [START retail_v2_generated_ProductService_AddFulfillmentPlaces_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 retail_v2 + + +def sample_add_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_AddFulfillmentPlaces_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_async.py new file mode 100644 index 00000000..0bba6386 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_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 AddLocalInventories +# 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-retail + + +# [START retail_v2_generated_ProductService_AddLocalInventories_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 retail_v2 + + +async def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_AddLocalInventories_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_sync.py new file mode 100644 index 00000000..584c251a --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_add_local_inventories_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 AddLocalInventories +# 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-retail + + +# [START retail_v2_generated_ProductService_AddLocalInventories_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 retail_v2 + + +def sample_add_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_AddLocalInventories_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_async.py new file mode 100644 index 00000000..48cae353 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +async def sample_create_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_CreateProduct_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_sync.py new file mode 100644 index 00000000..8431851d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_create_product_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +def sample_create_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_CreateProduct_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_delete_product_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_delete_product_async.py new file mode 100644 index 00000000..5db7dac8 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +async def sample_delete_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + +# [END retail_v2_generated_ProductService_DeleteProduct_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_delete_product_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_delete_product_sync.py new file mode 100644 index 00000000..eb289672 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +def sample_delete_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + +# [END retail_v2_generated_ProductService_DeleteProduct_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_get_product_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_get_product_async.py new file mode 100644 index 00000000..c8e5068c --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +async def sample_get_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_GetProduct_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_get_product_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_get_product_sync.py new file mode 100644 index 00000000..945d7fdc --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +def sample_get_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_GetProduct_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_async.py new file mode 100644 index 00000000..aad7c828 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_async.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportProducts +# 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-retail + + +# [START retail_v2_generated_ProductService_ImportProducts_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 retail_v2 + + +async def sample_import_products(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_ImportProducts_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_sync.py new file mode 100644 index 00000000..21150487 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_import_products_sync.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportProducts +# 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-retail + + +# [START retail_v2_generated_ProductService_ImportProducts_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 retail_v2 + + +def sample_import_products(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + input_config = retail_v2.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_ImportProducts_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_list_products_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_list_products_async.py new file mode 100644 index 00000000..ed3f73bf --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +async def sample_list_products(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.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 retail_v2_generated_ProductService_ListProducts_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_list_products_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_list_products_sync.py new file mode 100644 index 00000000..9aa5879d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +def sample_list_products(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.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 retail_v2_generated_ProductService_ListProducts_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_async.py new file mode 100644 index 00000000..b395a2e6 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveFulfillmentPlaces +# 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-retail + + +# [START retail_v2_generated_ProductService_RemoveFulfillmentPlaces_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 retail_v2 + + +async def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_RemoveFulfillmentPlaces_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_sync.py new file mode 100644 index 00000000..6bea8785 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_fulfillment_places_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveFulfillmentPlaces +# 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-retail + + +# [START retail_v2_generated_ProductService_RemoveFulfillmentPlaces_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 retail_v2 + + +def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_RemoveFulfillmentPlaces_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_async.py new file mode 100644 index 00000000..19666243 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveLocalInventories +# 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-retail + + +# [START retail_v2_generated_ProductService_RemoveLocalInventories_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 retail_v2 + + +async def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_RemoveLocalInventories_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_sync.py new file mode 100644 index 00000000..377b9d4c --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_remove_local_inventories_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveLocalInventories +# 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-retail + + +# [START retail_v2_generated_ProductService_RemoveLocalInventories_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 retail_v2 + + +def sample_remove_local_inventories(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_RemoveLocalInventories_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_async.py new file mode 100644 index 00000000..aca029a1 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_async.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetInventory +# 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-retail + + +# [START retail_v2_generated_ProductService_SetInventory_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 retail_v2 + + +async def sample_set_inventory(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + inventory = retail_v2.Product() + inventory.title = "title_value" + + request = retail_v2.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_SetInventory_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_sync.py new file mode 100644 index 00000000..005dde7b --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_set_inventory_sync.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetInventory +# 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-retail + + +# [START retail_v2_generated_ProductService_SetInventory_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 retail_v2 + + +def sample_set_inventory(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + inventory = retail_v2.Product() + inventory.title = "title_value" + + request = retail_v2.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_SetInventory_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_async.py new file mode 100644 index 00000000..375fff88 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_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 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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +async def sample_update_product(): + # Create a client + client = retail_v2.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.UpdateProductRequest( + product=product, + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_UpdateProduct_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_sync.py new file mode 100644 index 00000000..645965a3 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_product_service_update_product_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 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-retail + + +# [START retail_v2_generated_ProductService_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 retail_v2 + + +def sample_update_product(): + # Create a client + client = retail_v2.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2.Product() + product.title = "title_value" + + request = retail_v2.UpdateProductRequest( + product=product, + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ProductService_UpdateProduct_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_async.py new file mode 100644 index 00000000..ee6214dd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Search +# 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-retail + + +# [START retail_v2_generated_SearchService_Search_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 retail_v2 + + +async def sample_search(): + # Create a client + client = retail_v2.SearchServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2_generated_SearchService_Search_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_sync.py new file mode 100644 index 00000000..b62f941c --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_search_service_search_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Search +# 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-retail + + +# [START retail_v2_generated_SearchService_Search_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 retail_v2 + + +def sample_search(): + # Create a client + client = retail_v2.SearchServiceClient() + + # Initialize request argument(s) + request = retail_v2.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2_generated_SearchService_Search_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_async.py new file mode 100644 index 00000000..a81c278c --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_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 AddControl +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_AddControl_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 retail_v2 + + +async def sample_add_control(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.add_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_AddControl_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_sync.py new file mode 100644 index 00000000..6d4b233d --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_add_control_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 AddControl +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_AddControl_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 retail_v2 + + +def sample_add_control(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.add_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_AddControl_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_async.py new file mode 100644 index 00000000..1ebb03a5 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_CreateServingConfig_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 retail_v2 + + +async def sample_create_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = await client.create_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_CreateServingConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_sync.py new file mode 100644 index 00000000..7980b5dc --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_create_serving_config_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_CreateServingConfig_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 retail_v2 + + +def sample_create_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = client.create_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_CreateServingConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_async.py new file mode 100644 index 00000000..3b2a97b4 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_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 DeleteServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_DeleteServingConfig_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 retail_v2 + + +async def sample_delete_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_serving_config(request=request) + + +# [END retail_v2_generated_ServingConfigService_DeleteServingConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_sync.py new file mode 100644 index 00000000..4774bb67 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_delete_serving_config_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 DeleteServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_DeleteServingConfig_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 retail_v2 + + +def sample_delete_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_serving_config(request=request) + + +# [END retail_v2_generated_ServingConfigService_DeleteServingConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_async.py new file mode 100644 index 00000000..672d27fa --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_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 GetServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_GetServingConfig_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 retail_v2 + + +async def sample_get_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_GetServingConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_sync.py new file mode 100644 index 00000000..8595c9bb --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_get_serving_config_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 GetServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_GetServingConfig_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 retail_v2 + + +def sample_get_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_GetServingConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_async.py new file mode 100644 index 00000000..45802717 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_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 ListServingConfigs +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_ListServingConfigs_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 retail_v2 + + +async def sample_list_serving_configs(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2_generated_ServingConfigService_ListServingConfigs_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_sync.py new file mode 100644 index 00000000..f63568e0 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_list_serving_configs_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 ListServingConfigs +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_ListServingConfigs_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 retail_v2 + + +def sample_list_serving_configs(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2_generated_ServingConfigService_ListServingConfigs_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_async.py new file mode 100644 index 00000000..204f4643 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_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 RemoveControl +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_RemoveControl_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 retail_v2 + + +async def sample_remove_control(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.remove_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_RemoveControl_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_sync.py new file mode 100644 index 00000000..0e27f32a --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_remove_control_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 RemoveControl +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_RemoveControl_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 retail_v2 + + +def sample_remove_control(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.remove_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_RemoveControl_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_async.py new file mode 100644 index 00000000..639dbc90 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_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 UpdateServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_UpdateServingConfig_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 retail_v2 + + +async def sample_update_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = await client.update_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_UpdateServingConfig_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_sync.py new file mode 100644 index 00000000..c935e2bd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_serving_config_service_update_serving_config_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 UpdateServingConfig +# 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-retail + + +# [START retail_v2_generated_ServingConfigService_UpdateServingConfig_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 retail_v2 + + +def sample_update_serving_config(): + # Create a client + client = retail_v2.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = client.update_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_ServingConfigService_UpdateServingConfig_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_async.py new file mode 100644 index 00000000..ad065730 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CollectUserEvent +# 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-retail + + +# [START retail_v2_generated_UserEventService_CollectUserEvent_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 retail_v2 + + +async def sample_collect_user_event(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = await client.collect_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_CollectUserEvent_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_sync.py new file mode 100644 index 00000000..787c55ea --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_collect_user_event_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CollectUserEvent +# 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-retail + + +# [START retail_v2_generated_UserEventService_CollectUserEvent_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 retail_v2 + + +def sample_collect_user_event(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = client.collect_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_CollectUserEvent_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_async.py new file mode 100644 index 00000000..e92677fd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportUserEvents +# 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-retail + + +# [START retail_v2_generated_UserEventService_ImportUserEvents_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 retail_v2 + + +async def sample_import_user_events(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_ImportUserEvents_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_sync.py new file mode 100644 index 00000000..b2e46ed9 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_import_user_events_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportUserEvents +# 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-retail + + +# [START retail_v2_generated_UserEventService_ImportUserEvents_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 retail_v2 + + +def sample_import_user_events(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + input_config = retail_v2.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_ImportUserEvents_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_async.py new file mode 100644 index 00000000..1a681ddc --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 PurgeUserEvents +# 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-retail + + +# [START retail_v2_generated_UserEventService_PurgeUserEvents_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 retail_v2 + + +async def sample_purge_user_events(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_PurgeUserEvents_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_sync.py new file mode 100644 index 00000000..f079c816 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_purge_user_events_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 PurgeUserEvents +# 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-retail + + +# [START retail_v2_generated_UserEventService_PurgeUserEvents_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 retail_v2 + + +def sample_purge_user_events(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_PurgeUserEvents_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_async.py new file mode 100644 index 00000000..0071e102 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_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 RejoinUserEvents +# 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-retail + + +# [START retail_v2_generated_UserEventService_RejoinUserEvents_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 retail_v2 + + +async def sample_rejoin_user_events(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_RejoinUserEvents_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_sync.py new file mode 100644 index 00000000..c48f9f20 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_rejoin_user_events_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 RejoinUserEvents +# 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-retail + + +# [START retail_v2_generated_UserEventService_RejoinUserEvents_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 retail_v2 + + +def sample_rejoin_user_events(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_RejoinUserEvents_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_async.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_async.py new file mode 100644 index 00000000..4d4351a9 --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 WriteUserEvent +# 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-retail + + +# [START retail_v2_generated_UserEventService_WriteUserEvent_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 retail_v2 + + +async def sample_write_user_event(): + # Create a client + client = retail_v2.UserEventServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = await client.write_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_WriteUserEvent_async] diff --git a/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_sync.py b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_sync.py new file mode 100644 index 00000000..05a56ddd --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/retail_v2_generated_user_event_service_write_user_event_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 WriteUserEvent +# 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-retail + + +# [START retail_v2_generated_UserEventService_WriteUserEvent_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 retail_v2 + + +def sample_write_user_event(): + # Create a client + client = retail_v2.UserEventServiceClient() + + # Initialize request argument(s) + user_event = retail_v2.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = client.write_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2_generated_UserEventService_WriteUserEvent_sync] diff --git a/owl-bot-staging/v2/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json b/owl-bot-staging/v2/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json new file mode 100644 index 00000000..1a31fd9b --- /dev/null +++ b/owl-bot-staging/v2/samples/generated_samples/snippet_metadata_google.cloud.retail.v2.json @@ -0,0 +1,8212 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.retail.v2", + "version": "v2" + } + ], + "language": "PYTHON", + "name": "google-cloud-retail", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.add_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.AddCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "AddCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.AttributesConfig", + "shortName": "add_catalog_attribute" + }, + "description": "Sample for AddCatalogAttribute", + "file": "retail_v2_generated_catalog_service_add_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_AddCatalogAttribute_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": "retail_v2_generated_catalog_service_add_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.add_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.AddCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "AddCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.AttributesConfig", + "shortName": "add_catalog_attribute" + }, + "description": "Sample for AddCatalogAttribute", + "file": "retail_v2_generated_catalog_service_add_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_AddCatalogAttribute_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": "retail_v2_generated_catalog_service_add_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.get_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.GetAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetAttributesConfigRequest" + }, + { + "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.retail_v2.types.AttributesConfig", + "shortName": "get_attributes_config" + }, + "description": "Sample for GetAttributesConfig", + "file": "retail_v2_generated_catalog_service_get_attributes_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_GetAttributesConfig_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": "retail_v2_generated_catalog_service_get_attributes_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.get_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.GetAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetAttributesConfigRequest" + }, + { + "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.retail_v2.types.AttributesConfig", + "shortName": "get_attributes_config" + }, + "description": "Sample for GetAttributesConfig", + "file": "retail_v2_generated_catalog_service_get_attributes_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_GetAttributesConfig_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": "retail_v2_generated_catalog_service_get_attributes_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.get_completion_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.GetCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetCompletionConfigRequest" + }, + { + "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.retail_v2.types.CompletionConfig", + "shortName": "get_completion_config" + }, + "description": "Sample for GetCompletionConfig", + "file": "retail_v2_generated_catalog_service_get_completion_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_GetCompletionConfig_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": "retail_v2_generated_catalog_service_get_completion_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.get_completion_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.GetCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetCompletionConfigRequest" + }, + { + "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.retail_v2.types.CompletionConfig", + "shortName": "get_completion_config" + }, + "description": "Sample for GetCompletionConfig", + "file": "retail_v2_generated_catalog_service_get_completion_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_GetCompletionConfig_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": "retail_v2_generated_catalog_service_get_completion_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.get_default_branch", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.GetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.GetDefaultBranchResponse", + "shortName": "get_default_branch" + }, + "description": "Sample for GetDefaultBranch", + "file": "retail_v2_generated_catalog_service_get_default_branch_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_GetDefaultBranch_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": "retail_v2_generated_catalog_service_get_default_branch_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.get_default_branch", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.GetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.GetDefaultBranchResponse", + "shortName": "get_default_branch" + }, + "description": "Sample for GetDefaultBranch", + "file": "retail_v2_generated_catalog_service_get_default_branch_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_GetDefaultBranch_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": "retail_v2_generated_catalog_service_get_default_branch_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.list_catalogs", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.ListCatalogs", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ListCatalogs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListCatalogsRequest" + }, + { + "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.retail_v2.services.catalog_service.pagers.ListCatalogsAsyncPager", + "shortName": "list_catalogs" + }, + "description": "Sample for ListCatalogs", + "file": "retail_v2_generated_catalog_service_list_catalogs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_ListCatalogs_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": "retail_v2_generated_catalog_service_list_catalogs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.list_catalogs", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.ListCatalogs", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ListCatalogs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListCatalogsRequest" + }, + { + "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.retail_v2.services.catalog_service.pagers.ListCatalogsPager", + "shortName": "list_catalogs" + }, + "description": "Sample for ListCatalogs", + "file": "retail_v2_generated_catalog_service_list_catalogs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_ListCatalogs_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": "retail_v2_generated_catalog_service_list_catalogs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.remove_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "RemoveCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.AttributesConfig", + "shortName": "remove_catalog_attribute" + }, + "description": "Sample for RemoveCatalogAttribute", + "file": "retail_v2_generated_catalog_service_remove_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_RemoveCatalogAttribute_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_remove_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.remove_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.RemoveCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "RemoveCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.AttributesConfig", + "shortName": "remove_catalog_attribute" + }, + "description": "Sample for RemoveCatalogAttribute", + "file": "retail_v2_generated_catalog_service_remove_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_RemoveCatalogAttribute_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_remove_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.replace_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ReplaceCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ReplaceCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.AttributesConfig", + "shortName": "replace_catalog_attribute" + }, + "description": "Sample for ReplaceCatalogAttribute", + "file": "retail_v2_generated_catalog_service_replace_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_ReplaceCatalogAttribute_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": "retail_v2_generated_catalog_service_replace_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.replace_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.ReplaceCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ReplaceCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ReplaceCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.AttributesConfig", + "shortName": "replace_catalog_attribute" + }, + "description": "Sample for ReplaceCatalogAttribute", + "file": "retail_v2_generated_catalog_service_replace_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_ReplaceCatalogAttribute_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": "retail_v2_generated_catalog_service_replace_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.set_default_branch", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.SetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "SetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.SetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "set_default_branch" + }, + "description": "Sample for SetDefaultBranch", + "file": "retail_v2_generated_catalog_service_set_default_branch_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_SetDefaultBranch_async", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_set_default_branch_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.set_default_branch", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.SetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "SetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.SetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "set_default_branch" + }, + "description": "Sample for SetDefaultBranch", + "file": "retail_v2_generated_catalog_service_set_default_branch_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_SetDefaultBranch_sync", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_set_default_branch_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.update_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.UpdateAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateAttributesConfigRequest" + }, + { + "name": "attributes_config", + "type": "google.cloud.retail_v2.types.AttributesConfig" + }, + { + "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.retail_v2.types.AttributesConfig", + "shortName": "update_attributes_config" + }, + "description": "Sample for UpdateAttributesConfig", + "file": "retail_v2_generated_catalog_service_update_attributes_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_UpdateAttributesConfig_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_update_attributes_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.update_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.UpdateAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateAttributesConfigRequest" + }, + { + "name": "attributes_config", + "type": "google.cloud.retail_v2.types.AttributesConfig" + }, + { + "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.retail_v2.types.AttributesConfig", + "shortName": "update_attributes_config" + }, + "description": "Sample for UpdateAttributesConfig", + "file": "retail_v2_generated_catalog_service_update_attributes_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_UpdateAttributesConfig_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_update_attributes_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.update_catalog", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.UpdateCatalog", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCatalog" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateCatalogRequest" + }, + { + "name": "catalog", + "type": "google.cloud.retail_v2.types.Catalog" + }, + { + "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.retail_v2.types.Catalog", + "shortName": "update_catalog" + }, + "description": "Sample for UpdateCatalog", + "file": "retail_v2_generated_catalog_service_update_catalog_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_UpdateCatalog_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": "retail_v2_generated_catalog_service_update_catalog_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.update_catalog", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.UpdateCatalog", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCatalog" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateCatalogRequest" + }, + { + "name": "catalog", + "type": "google.cloud.retail_v2.types.Catalog" + }, + { + "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.retail_v2.types.Catalog", + "shortName": "update_catalog" + }, + "description": "Sample for UpdateCatalog", + "file": "retail_v2_generated_catalog_service_update_catalog_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_UpdateCatalog_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": "retail_v2_generated_catalog_service_update_catalog_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceAsyncClient.update_completion_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.UpdateCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateCompletionConfigRequest" + }, + { + "name": "completion_config", + "type": "google.cloud.retail_v2.types.CompletionConfig" + }, + { + "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.retail_v2.types.CompletionConfig", + "shortName": "update_completion_config" + }, + "description": "Sample for UpdateCompletionConfig", + "file": "retail_v2_generated_catalog_service_update_completion_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_UpdateCompletionConfig_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_update_completion_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2.CatalogServiceClient.update_completion_config", + "method": { + "fullName": "google.cloud.retail.v2.CatalogService.UpdateCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateCompletionConfigRequest" + }, + { + "name": "completion_config", + "type": "google.cloud.retail_v2.types.CompletionConfig" + }, + { + "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.retail_v2.types.CompletionConfig", + "shortName": "update_completion_config" + }, + "description": "Sample for UpdateCompletionConfig", + "file": "retail_v2_generated_catalog_service_update_completion_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CatalogService_UpdateCompletionConfig_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_catalog_service_update_completion_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CompletionServiceAsyncClient", + "shortName": "CompletionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CompletionServiceAsyncClient.complete_query", + "method": { + "fullName": "google.cloud.retail.v2.CompletionService.CompleteQuery", + "service": { + "fullName": "google.cloud.retail.v2.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "CompleteQuery" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CompleteQueryRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.CompleteQueryResponse", + "shortName": "complete_query" + }, + "description": "Sample for CompleteQuery", + "file": "retail_v2_generated_completion_service_complete_query_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CompletionService_CompleteQuery_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_completion_service_complete_query_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CompletionServiceClient", + "shortName": "CompletionServiceClient" + }, + "fullName": "google.cloud.retail_v2.CompletionServiceClient.complete_query", + "method": { + "fullName": "google.cloud.retail.v2.CompletionService.CompleteQuery", + "service": { + "fullName": "google.cloud.retail.v2.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "CompleteQuery" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CompleteQueryRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.CompleteQueryResponse", + "shortName": "complete_query" + }, + "description": "Sample for CompleteQuery", + "file": "retail_v2_generated_completion_service_complete_query_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CompletionService_CompleteQuery_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_completion_service_complete_query_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.CompletionServiceAsyncClient", + "shortName": "CompletionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.CompletionServiceAsyncClient.import_completion_data", + "method": { + "fullName": "google.cloud.retail.v2.CompletionService.ImportCompletionData", + "service": { + "fullName": "google.cloud.retail.v2.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "ImportCompletionData" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ImportCompletionDataRequest" + }, + { + "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_completion_data" + }, + "description": "Sample for ImportCompletionData", + "file": "retail_v2_generated_completion_service_import_completion_data_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CompletionService_ImportCompletionData_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_completion_service_import_completion_data_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.CompletionServiceClient", + "shortName": "CompletionServiceClient" + }, + "fullName": "google.cloud.retail_v2.CompletionServiceClient.import_completion_data", + "method": { + "fullName": "google.cloud.retail.v2.CompletionService.ImportCompletionData", + "service": { + "fullName": "google.cloud.retail.v2.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "ImportCompletionData" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ImportCompletionDataRequest" + }, + { + "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_completion_data" + }, + "description": "Sample for ImportCompletionData", + "file": "retail_v2_generated_completion_service_import_completion_data_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_CompletionService_ImportCompletionData_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_completion_service_import_completion_data_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient.create_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.CreateControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "CreateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateControlRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "control", + "type": "google.cloud.retail_v2.types.Control" + }, + { + "name": "control_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.retail_v2.types.Control", + "shortName": "create_control" + }, + "description": "Sample for CreateControl", + "file": "retail_v2_generated_control_service_create_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_CreateControl_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_control_service_create_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceClient.create_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.CreateControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "CreateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateControlRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "control", + "type": "google.cloud.retail_v2.types.Control" + }, + { + "name": "control_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.retail_v2.types.Control", + "shortName": "create_control" + }, + "description": "Sample for CreateControl", + "file": "retail_v2_generated_control_service_create_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_CreateControl_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_control_service_create_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient.delete_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.DeleteControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "DeleteControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteControlRequest" + }, + { + "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_control" + }, + "description": "Sample for DeleteControl", + "file": "retail_v2_generated_control_service_delete_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_DeleteControl_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": "retail_v2_generated_control_service_delete_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceClient.delete_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.DeleteControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "DeleteControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteControlRequest" + }, + { + "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_control" + }, + "description": "Sample for DeleteControl", + "file": "retail_v2_generated_control_service_delete_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_DeleteControl_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": "retail_v2_generated_control_service_delete_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient.get_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.GetControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "GetControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetControlRequest" + }, + { + "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.retail_v2.types.Control", + "shortName": "get_control" + }, + "description": "Sample for GetControl", + "file": "retail_v2_generated_control_service_get_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_GetControl_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": "retail_v2_generated_control_service_get_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceClient.get_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.GetControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "GetControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetControlRequest" + }, + { + "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.retail_v2.types.Control", + "shortName": "get_control" + }, + "description": "Sample for GetControl", + "file": "retail_v2_generated_control_service_get_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_GetControl_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": "retail_v2_generated_control_service_get_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient.list_controls", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.ListControls", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "ListControls" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListControlsRequest" + }, + { + "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.retail_v2.services.control_service.pagers.ListControlsAsyncPager", + "shortName": "list_controls" + }, + "description": "Sample for ListControls", + "file": "retail_v2_generated_control_service_list_controls_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_ListControls_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": "retail_v2_generated_control_service_list_controls_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceClient.list_controls", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.ListControls", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "ListControls" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListControlsRequest" + }, + { + "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.retail_v2.services.control_service.pagers.ListControlsPager", + "shortName": "list_controls" + }, + "description": "Sample for ListControls", + "file": "retail_v2_generated_control_service_list_controls_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_ListControls_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": "retail_v2_generated_control_service_list_controls_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceAsyncClient.update_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.UpdateControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "UpdateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateControlRequest" + }, + { + "name": "control", + "type": "google.cloud.retail_v2.types.Control" + }, + { + "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.retail_v2.types.Control", + "shortName": "update_control" + }, + "description": "Sample for UpdateControl", + "file": "retail_v2_generated_control_service_update_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_UpdateControl_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": "retail_v2_generated_control_service_update_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2.ControlServiceClient.update_control", + "method": { + "fullName": "google.cloud.retail.v2.ControlService.UpdateControl", + "service": { + "fullName": "google.cloud.retail.v2.ControlService", + "shortName": "ControlService" + }, + "shortName": "UpdateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateControlRequest" + }, + { + "name": "control", + "type": "google.cloud.retail_v2.types.Control" + }, + { + "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.retail_v2.types.Control", + "shortName": "update_control" + }, + "description": "Sample for UpdateControl", + "file": "retail_v2_generated_control_service_update_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ControlService_UpdateControl_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": "retail_v2_generated_control_service_update_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "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": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2_generated_model_service_create_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_CreateModel_async", + "segments": [ + { + "end": 61, + "start": 27, + "type": "FULL" + }, + { + "end": 61, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 58, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 62, + "start": 59, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_create_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "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": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2_generated_model_service_create_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_CreateModel_sync", + "segments": [ + { + "end": 61, + "start": 27, + "type": "FULL" + }, + { + "end": 61, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 58, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 62, + "start": 59, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_create_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteModelRequest" + }, + { + "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_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2_generated_model_service_delete_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_DeleteModel_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": "retail_v2_generated_model_service_delete_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteModelRequest" + }, + { + "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_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2_generated_model_service_delete_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_DeleteModel_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": "retail_v2_generated_model_service_delete_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetModelRequest" + }, + { + "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.retail_v2.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2_generated_model_service_get_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_GetModel_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": "retail_v2_generated_model_service_get_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetModelRequest" + }, + { + "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.retail_v2.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2_generated_model_service_get_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_GetModel_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": "retail_v2_generated_model_service_get_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListModelsRequest" + }, + { + "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.retail_v2.services.model_service.pagers.ListModelsAsyncPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2_generated_model_service_list_models_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ListModels_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": "retail_v2_generated_model_service_list_models_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListModelsRequest" + }, + { + "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.retail_v2.services.model_service.pagers.ListModelsPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2_generated_model_service_list_models_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ListModels_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": "retail_v2_generated_model_service_list_models_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PauseModelRequest" + }, + { + "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.retail_v2.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2_generated_model_service_pause_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_PauseModel_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": "retail_v2_generated_model_service_pause_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PauseModelRequest" + }, + { + "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.retail_v2.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2_generated_model_service_pause_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_PauseModel_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": "retail_v2_generated_model_service_pause_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ResumeModelRequest" + }, + { + "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.retail_v2.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2_generated_model_service_resume_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ResumeModel_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": "retail_v2_generated_model_service_resume_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ResumeModelRequest" + }, + { + "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.retail_v2.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2_generated_model_service_resume_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_ResumeModel_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": "retail_v2_generated_model_service_resume_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.TuneModelRequest" + }, + { + "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.api_core.operation_async.AsyncOperation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2_generated_model_service_tune_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_TuneModel_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": "retail_v2_generated_model_service_tune_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.TuneModelRequest" + }, + { + "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.api_core.operation.Operation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2_generated_model_service_tune_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_TuneModel_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": "retail_v2_generated_model_service_tune_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceAsyncClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "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.retail_v2.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2_generated_model_service_update_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_UpdateModel_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_update_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2.ModelServiceClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2.types.Model" + }, + { + "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.retail_v2.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2_generated_model_service_update_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ModelService_UpdateModel_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_model_service_update_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.PredictionServiceAsyncClient", + "shortName": "PredictionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.PredictionServiceAsyncClient.predict", + "method": { + "fullName": "google.cloud.retail.v2.PredictionService.Predict", + "service": { + "fullName": "google.cloud.retail.v2.PredictionService", + "shortName": "PredictionService" + }, + "shortName": "Predict" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PredictRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.PredictResponse", + "shortName": "predict" + }, + "description": "Sample for Predict", + "file": "retail_v2_generated_prediction_service_predict_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_PredictionService_Predict_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_prediction_service_predict_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.PredictionServiceClient", + "shortName": "PredictionServiceClient" + }, + "fullName": "google.cloud.retail_v2.PredictionServiceClient.predict", + "method": { + "fullName": "google.cloud.retail.v2.PredictionService.Predict", + "service": { + "fullName": "google.cloud.retail.v2.PredictionService", + "shortName": "PredictionService" + }, + "shortName": "Predict" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PredictRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.PredictResponse", + "shortName": "predict" + }, + "description": "Sample for Predict", + "file": "retail_v2_generated_prediction_service_predict_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_PredictionService_Predict_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_prediction_service_predict_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.add_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.AddFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "add_fulfillment_places" + }, + "description": "Sample for AddFulfillmentPlaces", + "file": "retail_v2_generated_product_service_add_fulfillment_places_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_AddFulfillmentPlaces_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_add_fulfillment_places_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.add_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.AddFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "add_fulfillment_places" + }, + "description": "Sample for AddFulfillmentPlaces", + "file": "retail_v2_generated_product_service_add_fulfillment_places_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_AddFulfillmentPlaces_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_add_fulfillment_places_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.add_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.AddLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddLocalInventoriesRequest" + }, + { + "name": "product", + "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": "add_local_inventories" + }, + "description": "Sample for AddLocalInventories", + "file": "retail_v2_generated_product_service_add_local_inventories_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_AddLocalInventories_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": "retail_v2_generated_product_service_add_local_inventories_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.add_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.AddLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddLocalInventoriesRequest" + }, + { + "name": "product", + "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": "add_local_inventories" + }, + "description": "Sample for AddLocalInventories", + "file": "retail_v2_generated_product_service_add_local_inventories_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_AddLocalInventories_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": "retail_v2_generated_product_service_add_local_inventories_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.create_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.CreateProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.retail_v2.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.retail_v2.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "retail_v2_generated_product_service_create_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_CreateProduct_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_create_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.create_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.CreateProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.retail_v2.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.retail_v2.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "retail_v2_generated_product_service_create_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_CreateProduct_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_create_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.delete_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.DeleteProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.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": "retail_v2_generated_product_service_delete_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_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": "retail_v2_generated_product_service_delete_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.delete_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.DeleteProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.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": "retail_v2_generated_product_service_delete_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_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": "retail_v2_generated_product_service_delete_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.get_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.GetProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.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.retail_v2.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "retail_v2_generated_product_service_get_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_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": "retail_v2_generated_product_service_get_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.get_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.GetProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.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.retail_v2.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "retail_v2_generated_product_service_get_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_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": "retail_v2_generated_product_service_get_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.import_products", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.ImportProducts", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "ImportProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ImportProductsRequest" + }, + { + "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_products" + }, + "description": "Sample for ImportProducts", + "file": "retail_v2_generated_product_service_import_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_ImportProducts_async", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_import_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.import_products", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.ImportProducts", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "ImportProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ImportProductsRequest" + }, + { + "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_products" + }, + "description": "Sample for ImportProducts", + "file": "retail_v2_generated_product_service_import_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_ImportProducts_sync", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_import_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.list_products", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.ListProducts", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.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.retail_v2.services.product_service.pagers.ListProductsAsyncPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "retail_v2_generated_product_service_list_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_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": "retail_v2_generated_product_service_list_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.list_products", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.ListProducts", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.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.retail_v2.services.product_service.pagers.ListProductsPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "retail_v2_generated_product_service_list_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_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": "retail_v2_generated_product_service_list_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.remove_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "remove_fulfillment_places" + }, + "description": "Sample for RemoveFulfillmentPlaces", + "file": "retail_v2_generated_product_service_remove_fulfillment_places_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_RemoveFulfillmentPlaces_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_remove_fulfillment_places_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.remove_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.RemoveFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "remove_fulfillment_places" + }, + "description": "Sample for RemoveFulfillmentPlaces", + "file": "retail_v2_generated_product_service_remove_fulfillment_places_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_RemoveFulfillmentPlaces_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_remove_fulfillment_places_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.remove_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.RemoveLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveLocalInventoriesRequest" + }, + { + "name": "product", + "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": "remove_local_inventories" + }, + "description": "Sample for RemoveLocalInventories", + "file": "retail_v2_generated_product_service_remove_local_inventories_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_RemoveLocalInventories_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_remove_local_inventories_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.remove_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.RemoveLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveLocalInventoriesRequest" + }, + { + "name": "product", + "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": "remove_local_inventories" + }, + "description": "Sample for RemoveLocalInventories", + "file": "retail_v2_generated_product_service_remove_local_inventories_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_RemoveLocalInventories_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_remove_local_inventories_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.set_inventory", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.SetInventory", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "SetInventory" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.SetInventoryRequest" + }, + { + "name": "inventory", + "type": "google.cloud.retail_v2.types.Product" + }, + { + "name": "set_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.api_core.operation_async.AsyncOperation", + "shortName": "set_inventory" + }, + "description": "Sample for SetInventory", + "file": "retail_v2_generated_product_service_set_inventory_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_SetInventory_async", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_set_inventory_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.set_inventory", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.SetInventory", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "SetInventory" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.SetInventoryRequest" + }, + { + "name": "inventory", + "type": "google.cloud.retail_v2.types.Product" + }, + { + "name": "set_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.api_core.operation.Operation", + "shortName": "set_inventory" + }, + "description": "Sample for SetInventory", + "file": "retail_v2_generated_product_service_set_inventory_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_SetInventory_sync", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_set_inventory_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceAsyncClient.update_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.UpdateProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.retail_v2.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.retail_v2.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "retail_v2_generated_product_service_update_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_UpdateProduct_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_update_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2.ProductServiceClient.update_product", + "method": { + "fullName": "google.cloud.retail.v2.ProductService.UpdateProduct", + "service": { + "fullName": "google.cloud.retail.v2.ProductService", + "shortName": "ProductService" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.retail_v2.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.retail_v2.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "retail_v2_generated_product_service_update_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ProductService_UpdateProduct_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_product_service_update_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.SearchServiceAsyncClient", + "shortName": "SearchServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.SearchServiceAsyncClient.search", + "method": { + "fullName": "google.cloud.retail.v2.SearchService.Search", + "service": { + "fullName": "google.cloud.retail.v2.SearchService", + "shortName": "SearchService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.SearchRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.services.search_service.pagers.SearchAsyncPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "retail_v2_generated_search_service_search_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_SearchService_Search_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_search_service_search_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.SearchServiceClient", + "shortName": "SearchServiceClient" + }, + "fullName": "google.cloud.retail_v2.SearchServiceClient.search", + "method": { + "fullName": "google.cloud.retail.v2.SearchService.Search", + "service": { + "fullName": "google.cloud.retail.v2.SearchService", + "shortName": "SearchService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.SearchRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.services.search_service.pagers.SearchPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "retail_v2_generated_search_service_search_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_SearchService_Search_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_search_service_search_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient.add_control", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.AddControl", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "AddControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.ServingConfig", + "shortName": "add_control" + }, + "description": "Sample for AddControl", + "file": "retail_v2_generated_serving_config_service_add_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_AddControl_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_serving_config_service_add_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient.add_control", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.AddControl", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "AddControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.AddControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.ServingConfig", + "shortName": "add_control" + }, + "description": "Sample for AddControl", + "file": "retail_v2_generated_serving_config_service_add_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_AddControl_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_serving_config_service_add_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient.create_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.CreateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "CreateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateServingConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2.types.ServingConfig" + }, + { + "name": "serving_config_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.retail_v2.types.ServingConfig", + "shortName": "create_serving_config" + }, + "description": "Sample for CreateServingConfig", + "file": "retail_v2_generated_serving_config_service_create_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_CreateServingConfig_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_serving_config_service_create_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient.create_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.CreateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "CreateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CreateServingConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2.types.ServingConfig" + }, + { + "name": "serving_config_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.retail_v2.types.ServingConfig", + "shortName": "create_serving_config" + }, + "description": "Sample for CreateServingConfig", + "file": "retail_v2_generated_serving_config_service_create_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_CreateServingConfig_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_serving_config_service_create_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient.delete_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.DeleteServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "DeleteServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteServingConfigRequest" + }, + { + "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_serving_config" + }, + "description": "Sample for DeleteServingConfig", + "file": "retail_v2_generated_serving_config_service_delete_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_DeleteServingConfig_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": "retail_v2_generated_serving_config_service_delete_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient.delete_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.DeleteServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "DeleteServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.DeleteServingConfigRequest" + }, + { + "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_serving_config" + }, + "description": "Sample for DeleteServingConfig", + "file": "retail_v2_generated_serving_config_service_delete_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_DeleteServingConfig_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": "retail_v2_generated_serving_config_service_delete_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient.get_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.GetServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "GetServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetServingConfigRequest" + }, + { + "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.retail_v2.types.ServingConfig", + "shortName": "get_serving_config" + }, + "description": "Sample for GetServingConfig", + "file": "retail_v2_generated_serving_config_service_get_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_GetServingConfig_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": "retail_v2_generated_serving_config_service_get_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient.get_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.GetServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "GetServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.GetServingConfigRequest" + }, + { + "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.retail_v2.types.ServingConfig", + "shortName": "get_serving_config" + }, + "description": "Sample for GetServingConfig", + "file": "retail_v2_generated_serving_config_service_get_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_GetServingConfig_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": "retail_v2_generated_serving_config_service_get_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient.list_serving_configs", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.ListServingConfigs", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "ListServingConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListServingConfigsRequest" + }, + { + "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.retail_v2.services.serving_config_service.pagers.ListServingConfigsAsyncPager", + "shortName": "list_serving_configs" + }, + "description": "Sample for ListServingConfigs", + "file": "retail_v2_generated_serving_config_service_list_serving_configs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_ListServingConfigs_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": "retail_v2_generated_serving_config_service_list_serving_configs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient.list_serving_configs", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.ListServingConfigs", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "ListServingConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ListServingConfigsRequest" + }, + { + "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.retail_v2.services.serving_config_service.pagers.ListServingConfigsPager", + "shortName": "list_serving_configs" + }, + "description": "Sample for ListServingConfigs", + "file": "retail_v2_generated_serving_config_service_list_serving_configs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_ListServingConfigs_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": "retail_v2_generated_serving_config_service_list_serving_configs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient.remove_control", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.RemoveControl", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "RemoveControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.ServingConfig", + "shortName": "remove_control" + }, + "description": "Sample for RemoveControl", + "file": "retail_v2_generated_serving_config_service_remove_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_RemoveControl_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_serving_config_service_remove_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient.remove_control", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.RemoveControl", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "RemoveControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RemoveControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.ServingConfig", + "shortName": "remove_control" + }, + "description": "Sample for RemoveControl", + "file": "retail_v2_generated_serving_config_service_remove_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_RemoveControl_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_serving_config_service_remove_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceAsyncClient.update_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.UpdateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "UpdateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateServingConfigRequest" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2.types.ServingConfig" + }, + { + "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.retail_v2.types.ServingConfig", + "shortName": "update_serving_config" + }, + "description": "Sample for UpdateServingConfig", + "file": "retail_v2_generated_serving_config_service_update_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_UpdateServingConfig_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": "retail_v2_generated_serving_config_service_update_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2.ServingConfigServiceClient.update_serving_config", + "method": { + "fullName": "google.cloud.retail.v2.ServingConfigService.UpdateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "UpdateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.UpdateServingConfigRequest" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2.types.ServingConfig" + }, + { + "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.retail_v2.types.ServingConfig", + "shortName": "update_serving_config" + }, + "description": "Sample for UpdateServingConfig", + "file": "retail_v2_generated_serving_config_service_update_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_ServingConfigService_UpdateServingConfig_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": "retail_v2_generated_serving_config_service_update_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient.collect_user_event", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.CollectUserEvent", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "CollectUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CollectUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api.httpbody_pb2.HttpBody", + "shortName": "collect_user_event" + }, + "description": "Sample for CollectUserEvent", + "file": "retail_v2_generated_user_event_service_collect_user_event_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_CollectUserEvent_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_collect_user_event_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceClient.collect_user_event", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.CollectUserEvent", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "CollectUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.CollectUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api.httpbody_pb2.HttpBody", + "shortName": "collect_user_event" + }, + "description": "Sample for CollectUserEvent", + "file": "retail_v2_generated_user_event_service_collect_user_event_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_CollectUserEvent_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_collect_user_event_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient.import_user_events", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.ImportUserEvents", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "ImportUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ImportUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for ImportUserEvents", + "file": "retail_v2_generated_user_event_service_import_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_ImportUserEvents_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_import_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceClient.import_user_events", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.ImportUserEvents", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "ImportUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.ImportUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for ImportUserEvents", + "file": "retail_v2_generated_user_event_service_import_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_ImportUserEvents_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_import_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient.purge_user_events", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.PurgeUserEvents", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "PurgeUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PurgeUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for PurgeUserEvents", + "file": "retail_v2_generated_user_event_service_purge_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_PurgeUserEvents_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_purge_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceClient.purge_user_events", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.PurgeUserEvents", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "PurgeUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.PurgeUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for PurgeUserEvents", + "file": "retail_v2_generated_user_event_service_purge_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_PurgeUserEvents_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_purge_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient.rejoin_user_events", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.RejoinUserEvents", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "RejoinUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RejoinUserEventsRequest" + }, + { + "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": "rejoin_user_events" + }, + "description": "Sample for RejoinUserEvents", + "file": "retail_v2_generated_user_event_service_rejoin_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_RejoinUserEvents_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": "retail_v2_generated_user_event_service_rejoin_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceClient.rejoin_user_events", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.RejoinUserEvents", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "RejoinUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.RejoinUserEventsRequest" + }, + { + "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": "rejoin_user_events" + }, + "description": "Sample for RejoinUserEvents", + "file": "retail_v2_generated_user_event_service_rejoin_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_RejoinUserEvents_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": "retail_v2_generated_user_event_service_rejoin_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceAsyncClient.write_user_event", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.WriteUserEvent", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "WriteUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.WriteUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.UserEvent", + "shortName": "write_user_event" + }, + "description": "Sample for WriteUserEvent", + "file": "retail_v2_generated_user_event_service_write_user_event_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_WriteUserEvent_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_write_user_event_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2.UserEventServiceClient.write_user_event", + "method": { + "fullName": "google.cloud.retail.v2.UserEventService.WriteUserEvent", + "service": { + "fullName": "google.cloud.retail.v2.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "WriteUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2.types.WriteUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2.types.UserEvent", + "shortName": "write_user_event" + }, + "description": "Sample for WriteUserEvent", + "file": "retail_v2_generated_user_event_service_write_user_event_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2_generated_UserEventService_WriteUserEvent_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2_generated_user_event_service_write_user_event_sync.py" + } + ] +} diff --git a/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py b/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py new file mode 100644 index 00000000..bd790175 --- /dev/null +++ b/owl-bot-staging/v2/scripts/fixup_retail_v2_keywords.py @@ -0,0 +1,226 @@ +#! /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 retailCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'add_catalog_attribute': ('attributes_config', 'catalog_attribute', ), + 'add_control': ('serving_config', 'control_id', ), + 'add_fulfillment_places': ('product', 'type_', 'place_ids', 'add_time', 'allow_missing', ), + 'add_local_inventories': ('product', 'local_inventories', 'add_mask', 'add_time', 'allow_missing', ), + 'collect_user_event': ('parent', 'user_event', 'prebuilt_rule', 'uri', 'ets', 'raw_json', ), + 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', 'entity', ), + 'create_control': ('parent', 'control', 'control_id', ), + 'create_model': ('parent', 'model', 'dry_run', ), + 'create_product': ('parent', 'product', 'product_id', ), + 'create_serving_config': ('parent', 'serving_config', 'serving_config_id', ), + 'delete_control': ('name', ), + 'delete_model': ('name', ), + 'delete_product': ('name', ), + 'delete_serving_config': ('name', ), + 'get_attributes_config': ('name', ), + 'get_completion_config': ('name', ), + 'get_control': ('name', ), + 'get_default_branch': ('catalog', ), + 'get_model': ('name', ), + 'get_product': ('name', ), + 'get_serving_config': ('name', ), + 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), + 'import_products': ('parent', 'input_config', 'request_id', 'errors_config', 'update_mask', 'reconciliation_mode', 'notification_pubsub_topic', ), + 'import_user_events': ('parent', 'input_config', 'errors_config', ), + 'list_catalogs': ('parent', 'page_size', 'page_token', ), + 'list_controls': ('parent', 'page_size', 'page_token', 'filter', ), + 'list_models': ('parent', 'page_size', 'page_token', ), + 'list_products': ('parent', 'page_size', 'page_token', 'filter', 'read_mask', ), + 'list_serving_configs': ('parent', 'page_size', 'page_token', ), + 'pause_model': ('name', ), + 'predict': ('placement', 'user_event', 'page_size', 'page_token', 'filter', 'validate_only', 'params', 'labels', ), + 'purge_user_events': ('parent', 'filter', 'force', ), + 'rejoin_user_events': ('parent', 'user_event_rejoin_scope', ), + 'remove_catalog_attribute': ('attributes_config', 'key', ), + 'remove_control': ('serving_config', 'control_id', ), + 'remove_fulfillment_places': ('product', 'type_', 'place_ids', 'remove_time', 'allow_missing', ), + 'remove_local_inventories': ('product', 'place_ids', 'remove_time', 'allow_missing', ), + 'replace_catalog_attribute': ('attributes_config', 'catalog_attribute', 'update_mask', ), + 'resume_model': ('name', ), + 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', 'entity', ), + 'set_default_branch': ('catalog', 'branch_id', 'note', 'force', ), + 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), + 'tune_model': ('name', ), + 'update_attributes_config': ('attributes_config', 'update_mask', ), + 'update_catalog': ('catalog', 'update_mask', ), + 'update_completion_config': ('completion_config', 'update_mask', ), + 'update_control': ('control', 'update_mask', ), + 'update_model': ('model', 'update_mask', ), + 'update_product': ('product', 'update_mask', 'allow_missing', ), + 'update_serving_config': ('serving_config', 'update_mask', ), + 'write_user_event': ('parent', 'user_event', 'write_async', ), + } + + 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=retailCallTransformer(), +): + """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 retail 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/v2/setup.py b/owl-bot-staging/v2/setup.py new file mode 100644 index 00000000..458c0728 --- /dev/null +++ b/owl-bot-staging/v2/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-retail' + + +description = "Google Cloud Retail API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/retail/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-retail" + +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/v2/testing/constraints-3.10.txt b/owl-bot-staging/v2/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2/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/v2/testing/constraints-3.11.txt b/owl-bot-staging/v2/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2/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/v2/testing/constraints-3.12.txt b/owl-bot-staging/v2/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2/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/v2/testing/constraints-3.7.txt b/owl-bot-staging/v2/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v2/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/v2/testing/constraints-3.8.txt b/owl-bot-staging/v2/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2/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/v2/testing/constraints-3.9.txt b/owl-bot-staging/v2/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2/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/v2/tests/__init__.py b/owl-bot-staging/v2/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2/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/v2/tests/unit/__init__.py b/owl-bot-staging/v2/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2/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/v2/tests/unit/gapic/__init__.py b/owl-bot-staging/v2/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2/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/v2/tests/unit/gapic/retail_v2/__init__.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/__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/v2/tests/unit/gapic/retail_v2/test_catalog_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py new file mode 100644 index 00000000..ba76cf3d --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_catalog_service.py @@ -0,0 +1,6646 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.catalog_service import CatalogServiceAsyncClient +from google.cloud.retail_v2.services.catalog_service import CatalogServiceClient +from google.cloud.retail_v2.services.catalog_service import pagers +from google.cloud.retail_v2.services.catalog_service import transports +from google.cloud.retail_v2.types import catalog +from google.cloud.retail_v2.types import catalog as gcr_catalog +from google.cloud.retail_v2.types import catalog_service +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.type import date_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 CatalogServiceClient._get_default_mtls_endpoint(None) is None + assert CatalogServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (CatalogServiceClient, "grpc"), + (CatalogServiceAsyncClient, "grpc_asyncio"), + (CatalogServiceClient, "rest"), +]) +def test_catalog_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CatalogServiceGrpcTransport, "grpc"), + (transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.CatalogServiceRestTransport, "rest"), +]) +def test_catalog_service_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", [ + (CatalogServiceClient, "grpc"), + (CatalogServiceAsyncClient, "grpc_asyncio"), + (CatalogServiceClient, "rest"), +]) +def test_catalog_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_catalog_service_client_get_transport_class(): + transport = CatalogServiceClient.get_transport_class() + available_transports = [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceRestTransport, + ] + assert transport in available_transports + + transport = CatalogServiceClient.get_transport_class("grpc") + assert transport == transports.CatalogServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_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(CatalogServiceClient, '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(CatalogServiceClient, '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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "true"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "false"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", "true"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_catalog_service_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", [ + CatalogServiceClient, CatalogServiceAsyncClient +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest"), +]) +def test_catalog_service_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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", grpc_helpers), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", None), +]) +def test_catalog_service_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_catalog_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CatalogServiceClient( + 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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", grpc_helpers), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_catalog_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ListCatalogsRequest, + dict, +]) +def test_list_catalogs(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_catalogs_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 = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + client.list_catalogs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + +@pytest.mark.asyncio +async def test_list_catalogs_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ListCatalogsRequest): + client = CatalogServiceAsyncClient( + 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_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_catalogs_async_from_dict(): + await test_list_catalogs_async(request_type=dict) + + +def test_list_catalogs_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = catalog_service.ListCatalogsResponse() + client.list_catalogs(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_catalogs_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.ListCatalogsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + await client.list_catalogs(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_catalogs_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_catalogs( + 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_catalogs_flattened_error(): + client = CatalogServiceClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_catalogs_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_catalogs( + 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_catalogs_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + + +def test_list_catalogs_pager(transport_name: str = "grpc"): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_catalogs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in results) +def test_list_catalogs_pages(transport_name: str = "grpc"): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + pages = list(client.list_catalogs(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_catalogs_async_pager(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_catalogs(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, catalog.Catalog) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_catalogs_async_pages(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + 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_catalogs(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", [ + catalog_service.UpdateCatalogRequest, + dict, +]) +def test_update_catalog(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + ) + response = client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_catalog_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 = CatalogServiceClient( + 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_catalog), + '__call__') as call: + client.update_catalog() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + +@pytest.mark.asyncio +async def test_update_catalog_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCatalogRequest): + client = CatalogServiceAsyncClient( + 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_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + )) + response = await client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_update_catalog_async_from_dict(): + await test_update_catalog_async(request_type=dict) + + +def test_update_catalog_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = gcr_catalog.Catalog() + client.update_catalog(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', + 'catalog.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_catalog_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + await client.update_catalog(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', + 'catalog.name=name_value', + ) in kw['metadata'] + + +def test_update_catalog_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_catalog( + catalog=gcr_catalog.Catalog(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].catalog + mock_val = gcr_catalog.Catalog(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_catalog_flattened_error(): + client = CatalogServiceClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_catalog_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_catalog( + catalog=gcr_catalog.Catalog(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].catalog + mock_val = gcr_catalog.Catalog(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_catalog_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.SetDefaultBranchRequest, + dict, +]) +def test_set_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_set_default_branch_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 = CatalogServiceClient( + 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.set_default_branch), + '__call__') as call: + client.set_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + +@pytest.mark.asyncio +async def test_set_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.SetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + 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.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_set_default_branch_async_from_dict(): + await test_set_default_branch_async(request_type=dict) + + +def test_set_default_branch_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = None + client.set_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.set_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +def test_set_default_branch_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__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.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_set_default_branch_flattened_error(): + client = CatalogServiceClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__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.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetDefaultBranchRequest, + dict, +]) +def test_get_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + ) + response = client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +def test_get_default_branch_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 = CatalogServiceClient( + 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_default_branch), + '__call__') as call: + client.get_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + +@pytest.mark.asyncio +async def test_get_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + 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_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + )) + response = await client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +@pytest.mark.asyncio +async def test_get_default_branch_async_from_dict(): + await test_get_default_branch_async(request_type=dict) + + +def test_get_default_branch_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = catalog_service.GetDefaultBranchResponse() + client.get_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + await client.get_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +def test_get_default_branch_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_get_default_branch_flattened_error(): + client = CatalogServiceClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetCompletionConfigRequest, + dict, +]) +def test_get_completion_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + response = client.get_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_get_completion_config_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 = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + client.get_completion_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + +@pytest.mark.asyncio +async def test_get_completion_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetCompletionConfigRequest): + client = CatalogServiceAsyncClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + )) + response = await client.get_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +@pytest.mark.asyncio +async def test_get_completion_config_async_from_dict(): + await test_get_completion_config_async(request_type=dict) + + +def test_get_completion_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetCompletionConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + call.return_value = catalog.CompletionConfig() + client.get_completion_config(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_completion_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetCompletionConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + await client.get_completion_config(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_completion_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_completion_config( + 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_completion_config_flattened_error(): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_completion_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_completion_config( + 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_completion_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateCompletionConfigRequest, + dict, +]) +def test_update_completion_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + response = client.update_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_update_completion_config_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 = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + client.update_completion_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + +@pytest.mark.asyncio +async def test_update_completion_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCompletionConfigRequest): + client = CatalogServiceAsyncClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + )) + response = await client.update_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +@pytest.mark.asyncio +async def test_update_completion_config_async_from_dict(): + await test_update_completion_config_async(request_type=dict) + + +def test_update_completion_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateCompletionConfigRequest() + + request.completion_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + call.return_value = catalog.CompletionConfig() + client.update_completion_config(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', + 'completion_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_completion_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateCompletionConfigRequest() + + request.completion_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + await client.update_completion_config(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', + 'completion_config.name=name_value', + ) in kw['metadata'] + + +def test_update_completion_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_completion_config( + completion_config=catalog.CompletionConfig(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].completion_config + mock_val = catalog.CompletionConfig(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_completion_config_flattened_error(): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_completion_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_completion_config( + completion_config=catalog.CompletionConfig(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].completion_config + mock_val = catalog.CompletionConfig(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_completion_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetAttributesConfigRequest, + dict, +]) +def test_get_attributes_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.get_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_get_attributes_config_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 = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + client.get_attributes_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + +@pytest.mark.asyncio +async def test_get_attributes_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetAttributesConfigRequest): + client = CatalogServiceAsyncClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.get_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_get_attributes_config_async_from_dict(): + await test_get_attributes_config_async(request_type=dict) + + +def test_get_attributes_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetAttributesConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.get_attributes_config(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_attributes_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetAttributesConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.get_attributes_config(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_attributes_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_attributes_config( + 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_attributes_config_flattened_error(): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_attributes_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_attributes_config( + 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_attributes_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateAttributesConfigRequest, + dict, +]) +def test_update_attributes_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.update_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_update_attributes_config_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 = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + client.update_attributes_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + +@pytest.mark.asyncio +async def test_update_attributes_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateAttributesConfigRequest): + client = CatalogServiceAsyncClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.update_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_update_attributes_config_async_from_dict(): + await test_update_attributes_config_async(request_type=dict) + + +def test_update_attributes_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateAttributesConfigRequest() + + request.attributes_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.update_attributes_config(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', + 'attributes_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_attributes_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateAttributesConfigRequest() + + request.attributes_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.update_attributes_config(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', + 'attributes_config.name=name_value', + ) in kw['metadata'] + + +def test_update_attributes_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_attributes_config( + attributes_config=catalog.AttributesConfig(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].attributes_config + mock_val = catalog.AttributesConfig(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_attributes_config_flattened_error(): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_attributes_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_attributes_config( + attributes_config=catalog.AttributesConfig(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].attributes_config + mock_val = catalog.AttributesConfig(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_attributes_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.AddCatalogAttributeRequest, + dict, +]) +def test_add_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.add_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_add_catalog_attribute_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 = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + client.add_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_add_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.AddCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.add_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_add_catalog_attribute_async_from_dict(): + await test_add_catalog_attribute_async(request_type=dict) + + +def test_add_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.AddCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.add_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.AddCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.add_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.RemoveCatalogAttributeRequest, + dict, +]) +def test_remove_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.remove_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_remove_catalog_attribute_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 = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + client.remove_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.RemoveCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.remove_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_async_from_dict(): + await test_remove_catalog_attribute_async(request_type=dict) + + +def test_remove_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.RemoveCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.remove_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.RemoveCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.remove_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ReplaceCatalogAttributeRequest, + dict, +]) +def test_replace_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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.replace_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.replace_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_replace_catalog_attribute_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 = CatalogServiceClient( + 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.replace_catalog_attribute), + '__call__') as call: + client.replace_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ReplaceCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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.replace_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.replace_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_async_from_dict(): + await test_replace_catalog_attribute_async(request_type=dict) + + +def test_replace_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.ReplaceCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.replace_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.replace_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.ReplaceCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.replace_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.replace_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ListCatalogsRequest, + dict, +]) +def test_list_catalogs_rest(request_type): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_catalogs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_catalogs_rest_required_fields(request_type=catalog_service.ListCatalogsRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_catalogs._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_catalogs._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog_service.ListCatalogsResponse() + # 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 + + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_catalogs(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_catalogs_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_catalogs._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_catalogs_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_list_catalogs") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_list_catalogs") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.ListCatalogsRequest.pb(catalog_service.ListCatalogsRequest()) + 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 = catalog_service.ListCatalogsResponse.to_json(catalog_service.ListCatalogsResponse()) + + request = catalog_service.ListCatalogsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.ListCatalogsResponse() + + client.list_catalogs(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_catalogs_rest_bad_request(transport: str = 'rest', request_type=catalog_service.ListCatalogsRequest): + client = CatalogServiceClient( + 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_catalogs(request) + + +def test_list_catalogs_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsResponse() + + # 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 + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_catalogs(**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/v2/{parent=projects/*/locations/*}/catalogs" % client.transport._host, args[1]) + + +def test_list_catalogs_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + + +def test_list_catalogs_rest_pager(transport: str = 'rest'): + client = CatalogServiceClient( + 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 = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(catalog_service.ListCatalogsResponse.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_catalogs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in results) + + pages = list(client.list_catalogs(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", [ + catalog_service.UpdateCatalogRequest, + dict, +]) +def test_update_catalog_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + request_init["catalog"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3', 'display_name': 'display_name_value', 'product_level_config': {'ingestion_product_type': 'ingestion_product_type_value', 'merchant_center_product_id_field': 'merchant_center_product_id_field_value'}} + 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 = gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_catalog(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_catalog_rest_required_fields(request_type=catalog_service.UpdateCatalogRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_catalog._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_catalog._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_catalog.Catalog() + # 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 + + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_catalog(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_catalog_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_catalog._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("catalog", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_catalog_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_catalog") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_catalog") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateCatalogRequest.pb(catalog_service.UpdateCatalogRequest()) + 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 = gcr_catalog.Catalog.to_json(gcr_catalog.Catalog()) + + request = catalog_service.UpdateCatalogRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_catalog.Catalog() + + client.update_catalog(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_catalog_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateCatalogRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + request_init["catalog"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3', 'display_name': 'display_name_value', 'product_level_config': {'ingestion_product_type': 'ingestion_product_type_value', 'merchant_center_product_id_field': 'merchant_center_product_id_field_value'}} + 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_catalog(request) + + +def test_update_catalog_rest_flattened(): + client = CatalogServiceClient( + 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 = gcr_catalog.Catalog() + + # get arguments that satisfy an http rule for this method + sample_request = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + catalog=gcr_catalog.Catalog(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 + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_catalog(**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/v2/{catalog.name=projects/*/locations/*/catalogs/*}" % client.transport._host, args[1]) + + +def test_update_catalog_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_catalog_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.SetDefaultBranchRequest, + dict, +]) +def test_set_default_branch_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.set_default_branch(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_default_branch_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "pre_set_default_branch") as pre: + pre.assert_not_called() + pb_message = catalog_service.SetDefaultBranchRequest.pb(catalog_service.SetDefaultBranchRequest()) + 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 = catalog_service.SetDefaultBranchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.set_default_branch(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_set_default_branch_rest_bad_request(transport: str = 'rest', request_type=catalog_service.SetDefaultBranchRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.set_default_branch(request) + + +def test_set_default_branch_rest_flattened(): + client = CatalogServiceClient( + 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 = {'catalog': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + catalog='catalog_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.set_default_branch(**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/v2/{catalog=projects/*/locations/*/catalogs/*}:setDefaultBranch" % client.transport._host, args[1]) + + +def test_set_default_branch_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +def test_set_default_branch_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetDefaultBranchRequest, + dict, +]) +def test_get_default_branch_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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 = catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.GetDefaultBranchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_default_branch(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_default_branch_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_default_branch") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_default_branch") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetDefaultBranchRequest.pb(catalog_service.GetDefaultBranchRequest()) + 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 = catalog_service.GetDefaultBranchResponse.to_json(catalog_service.GetDefaultBranchResponse()) + + request = catalog_service.GetDefaultBranchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.GetDefaultBranchResponse() + + client.get_default_branch(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_default_branch_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetDefaultBranchRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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_default_branch(request) + + +def test_get_default_branch_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog_service.GetDefaultBranchResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'catalog': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + catalog='catalog_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.GetDefaultBranchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_default_branch(**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/v2/{catalog=projects/*/locations/*/catalogs/*}:getDefaultBranch" % client.transport._host, args[1]) + + +def test_get_default_branch_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +def test_get_default_branch_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetCompletionConfigRequest, + dict, +]) +def test_get_completion_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + 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 = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_completion_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_get_completion_config_rest_required_fields(request_type=catalog_service.GetCompletionConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_completion_config._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_completion_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.CompletionConfig() + # 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 + + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_completion_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_completion_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_completion_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_completion_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_completion_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_completion_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetCompletionConfigRequest.pb(catalog_service.GetCompletionConfigRequest()) + 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 = catalog.CompletionConfig.to_json(catalog.CompletionConfig()) + + request = catalog_service.GetCompletionConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.CompletionConfig() + + client.get_completion_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_completion_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetCompletionConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + 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_completion_config(request) + + +def test_get_completion_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.CompletionConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + + # 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 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_completion_config(**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/v2/{name=projects/*/locations/*/catalogs/*/completionConfig}" % client.transport._host, args[1]) + + +def test_get_completion_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + + +def test_get_completion_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateCompletionConfigRequest, + dict, +]) +def test_update_completion_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + request_init["completion_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig', 'matching_order': 'matching_order_value', 'max_suggestions': 1632, 'min_prefix_length': 1810, 'auto_learning': True, 'suggestions_input_config': {'big_query_source': {'partition_date': {'year': 433, 'month': 550, 'day': 318}, 'project_id': 'project_id_value', 'dataset_id': 'dataset_id_value', 'table_id': 'table_id_value', 'gcs_staging_dir': 'gcs_staging_dir_value', 'data_schema': 'data_schema_value'}}, 'last_suggestions_import_operation': 'last_suggestions_import_operation_value', 'denylist_input_config': {}, 'last_denylist_import_operation': 'last_denylist_import_operation_value', 'allowlist_input_config': {}, 'last_allowlist_import_operation': 'last_allowlist_import_operation_value'} + 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 = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_completion_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_update_completion_config_rest_required_fields(request_type=catalog_service.UpdateCompletionConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_completion_config._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_completion_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.CompletionConfig() + # 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 + + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_completion_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_completion_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_completion_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("completionConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_completion_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_completion_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_completion_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateCompletionConfigRequest.pb(catalog_service.UpdateCompletionConfigRequest()) + 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 = catalog.CompletionConfig.to_json(catalog.CompletionConfig()) + + request = catalog_service.UpdateCompletionConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.CompletionConfig() + + client.update_completion_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_completion_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateCompletionConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + request_init["completion_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig', 'matching_order': 'matching_order_value', 'max_suggestions': 1632, 'min_prefix_length': 1810, 'auto_learning': True, 'suggestions_input_config': {'big_query_source': {'partition_date': {'year': 433, 'month': 550, 'day': 318}, 'project_id': 'project_id_value', 'dataset_id': 'dataset_id_value', 'table_id': 'table_id_value', 'gcs_staging_dir': 'gcs_staging_dir_value', 'data_schema': 'data_schema_value'}}, 'last_suggestions_import_operation': 'last_suggestions_import_operation_value', 'denylist_input_config': {}, 'last_denylist_import_operation': 'last_denylist_import_operation_value', 'allowlist_input_config': {}, 'last_allowlist_import_operation': 'last_allowlist_import_operation_value'} + 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_completion_config(request) + + +def test_update_completion_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.CompletionConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + + # get truthy value for each flattened field + mock_args = dict( + completion_config=catalog.CompletionConfig(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 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_completion_config(**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/v2/{completion_config.name=projects/*/locations/*/catalogs/*/completionConfig}" % client.transport._host, args[1]) + + +def test_update_completion_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_completion_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetAttributesConfigRequest, + dict, +]) +def test_get_attributes_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_attributes_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_get_attributes_config_rest_required_fields(request_type=catalog_service.GetAttributesConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_attributes_config._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_attributes_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_attributes_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_attributes_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_attributes_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_attributes_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_attributes_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_attributes_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetAttributesConfigRequest.pb(catalog_service.GetAttributesConfigRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.GetAttributesConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.get_attributes_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_attributes_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetAttributesConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_attributes_config(request) + + +def test_get_attributes_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.AttributesConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + + # 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 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_attributes_config(**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/v2/{name=projects/*/locations/*/catalogs/*/attributesConfig}" % client.transport._host, args[1]) + + +def test_get_attributes_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + + +def test_get_attributes_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateAttributesConfigRequest, + dict, +]) +def test_update_attributes_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + request_init["attributes_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig', 'catalog_attributes': {}, 'attribute_config_level': 1} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_attributes_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_update_attributes_config_rest_required_fields(request_type=catalog_service.UpdateAttributesConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_attributes_config._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_attributes_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_attributes_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_attributes_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_attributes_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("attributesConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_attributes_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_attributes_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_attributes_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateAttributesConfigRequest.pb(catalog_service.UpdateAttributesConfigRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.UpdateAttributesConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.update_attributes_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_attributes_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateAttributesConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + request_init["attributes_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig', 'catalog_attributes': {}, 'attribute_config_level': 1} + 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_attributes_config(request) + + +def test_update_attributes_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.AttributesConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + + # get truthy value for each flattened field + mock_args = dict( + attributes_config=catalog.AttributesConfig(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 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_attributes_config(**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/v2/{attributes_config.name=projects/*/locations/*/catalogs/*/attributesConfig}" % client.transport._host, args[1]) + + +def test_update_attributes_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_attributes_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.AddCatalogAttributeRequest, + dict, +]) +def test_add_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_add_catalog_attribute_rest_required_fields(request_type=catalog_service.AddCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + 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_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "catalogAttribute", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_add_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_add_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.AddCatalogAttributeRequest.pb(catalog_service.AddCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.AddCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.add_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.AddCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_catalog_attribute(request) + + +def test_add_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.RemoveCatalogAttributeRequest, + dict, +]) +def test_remove_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_remove_catalog_attribute_rest_required_fields(request_type=catalog_service.RemoveCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + request_init["key"] = "" + 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_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + jsonified_request["key"] = 'key_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + assert "key" in jsonified_request + assert jsonified_request["key"] == 'key_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "key", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_remove_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_remove_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.RemoveCatalogAttributeRequest.pb(catalog_service.RemoveCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.RemoveCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.remove_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.RemoveCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_catalog_attribute(request) + + +def test_remove_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ReplaceCatalogAttributeRequest, + dict, +]) +def test_replace_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.replace_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_replace_catalog_attribute_rest_required_fields(request_type=catalog_service.ReplaceCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + 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()).replace_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).replace_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.replace_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_replace_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.replace_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "catalogAttribute", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_replace_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_replace_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_replace_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.ReplaceCatalogAttributeRequest.pb(catalog_service.ReplaceCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.ReplaceCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.replace_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_replace_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.ReplaceCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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.replace_catalog_attribute(request) + + +def test_replace_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CatalogServiceClient( + 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 = CatalogServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CatalogServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CatalogServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + transports.CatalogServiceRestTransport, +]) +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 = CatalogServiceClient.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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CatalogServiceGrpcTransport, + ) + +def test_catalog_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_catalog_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.catalog_service.transports.CatalogServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_catalogs', + 'update_catalog', + 'set_default_branch', + 'get_default_branch', + 'get_completion_config', + 'update_completion_config', + 'get_attributes_config', + 'update_attributes_config', + 'add_catalog_attribute', + 'remove_catalog_attribute', + 'replace_catalog_attribute', + 'get_operation', + 'list_operations', + ) + 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_catalog_service_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.retail_v2.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_catalog_service_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.retail_v2.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport() + adc.assert_called_once() + + +def test_catalog_service_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) + CatalogServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + ], +) +def test_catalog_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + transports.CatalogServiceRestTransport, + ], +) +def test_catalog_service_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.CatalogServiceGrpcTransport, grpc_helpers), + (transports.CatalogServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_catalog_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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_catalog_service_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.CatalogServiceRestTransport ( + 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_catalog_service_host_no_port(transport_name): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_catalog_service_host_with_port(transport_name): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_catalog_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CatalogServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CatalogServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_catalogs._session + session2 = client2.transport.list_catalogs._session + assert session1 != session2 + session1 = client1.transport.update_catalog._session + session2 = client2.transport.update_catalog._session + assert session1 != session2 + session1 = client1.transport.set_default_branch._session + session2 = client2.transport.set_default_branch._session + assert session1 != session2 + session1 = client1.transport.get_default_branch._session + session2 = client2.transport.get_default_branch._session + assert session1 != session2 + session1 = client1.transport.get_completion_config._session + session2 = client2.transport.get_completion_config._session + assert session1 != session2 + session1 = client1.transport.update_completion_config._session + session2 = client2.transport.update_completion_config._session + assert session1 != session2 + session1 = client1.transport.get_attributes_config._session + session2 = client2.transport.get_attributes_config._session + assert session1 != session2 + session1 = client1.transport.update_attributes_config._session + session2 = client2.transport.update_attributes_config._session + assert session1 != session2 + session1 = client1.transport.add_catalog_attribute._session + session2 = client2.transport.add_catalog_attribute._session + assert session1 != session2 + session1 = client1.transport.remove_catalog_attribute._session + session2 = client2.transport.remove_catalog_attribute._session + assert session1 != session2 + session1 = client1.transport.replace_catalog_attribute._session + session2 = client2.transport.replace_catalog_attribute._session + assert session1 != session2 +def test_catalog_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcTransport( + 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_catalog_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcAsyncIOTransport( + 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.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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_attributes_config_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/attributesConfig".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.attributes_config_path(project, location, catalog) + assert expected == actual + + +def test_parse_attributes_config_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = CatalogServiceClient.attributes_config_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_attributes_config_path(path) + assert expected == actual + +def test_branch_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + branch = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = CatalogServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "branch": "clam", + } + path = CatalogServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_branch_path(path) + assert expected == actual + +def test_catalog_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "catalog": "mussel", + } + path = CatalogServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_completion_config_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/completionConfig".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.completion_config_path(project, location, catalog) + assert expected == actual + + +def test_parse_completion_config_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + } + path = CatalogServiceClient.completion_config_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_completion_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CatalogServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = CatalogServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = CatalogServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = CatalogServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CatalogServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = CatalogServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = CatalogServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = CatalogServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CatalogServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = CatalogServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.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.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CatalogServiceClient.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 = CatalogServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = CatalogServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = CatalogServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = CatalogServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = CatalogServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CatalogServiceClient( + 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 = CatalogServiceClient( + 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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_completion_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py new file mode 100644 index 00000000..f42c7b56 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_completion_service.py @@ -0,0 +1,2307 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.completion_service import CompletionServiceAsyncClient +from google.cloud.retail_v2.services.completion_service import CompletionServiceClient +from google.cloud.retail_v2.services.completion_service import transports +from google.cloud.retail_v2.types import completion_service +from google.cloud.retail_v2.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.type import date_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 CompletionServiceClient._get_default_mtls_endpoint(None) is None + assert CompletionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (CompletionServiceClient, "grpc"), + (CompletionServiceAsyncClient, "grpc_asyncio"), + (CompletionServiceClient, "rest"), +]) +def test_completion_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CompletionServiceGrpcTransport, "grpc"), + (transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.CompletionServiceRestTransport, "rest"), +]) +def test_completion_service_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", [ + (CompletionServiceClient, "grpc"), + (CompletionServiceAsyncClient, "grpc_asyncio"), + (CompletionServiceClient, "rest"), +]) +def test_completion_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_completion_service_client_get_transport_class(): + transport = CompletionServiceClient.get_transport_class() + available_transports = [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceRestTransport, + ] + assert transport in available_transports + + transport = CompletionServiceClient.get_transport_class("grpc") + assert transport == transports.CompletionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_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(CompletionServiceClient, '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(CompletionServiceClient, '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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "true"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "false"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", "true"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_completion_service_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", [ + CompletionServiceClient, CompletionServiceAsyncClient +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest"), +]) +def test_completion_service_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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", grpc_helpers), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", None), +]) +def test_completion_service_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_completion_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CompletionServiceClient( + 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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", grpc_helpers), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_completion_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + completion_service.CompleteQueryRequest, + dict, +]) +def test_complete_query(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + ) + response = client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +def test_complete_query_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 = CompletionServiceClient( + 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.complete_query), + '__call__') as call: + client.complete_query() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + +@pytest.mark.asyncio +async def test_complete_query_async(transport: str = 'grpc_asyncio', request_type=completion_service.CompleteQueryRequest): + client = CompletionServiceAsyncClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + )) + response = await client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +@pytest.mark.asyncio +async def test_complete_query_async_from_dict(): + await test_complete_query_async(request_type=dict) + + +def test_complete_query_field_headers(): + client = CompletionServiceClient( + 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 = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = completion_service.CompleteQueryResponse() + client.complete_query(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_complete_query_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse()) + await client.complete_query(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportCompletionDataRequest, + dict, +]) +def test_import_completion_data(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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_completion_data), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_completion_data_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 = CompletionServiceClient( + 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_completion_data), + '__call__') as call: + client.import_completion_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + +@pytest.mark.asyncio +async def test_import_completion_data_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportCompletionDataRequest): + client = CompletionServiceAsyncClient( + 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_completion_data), + '__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_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_completion_data_async_from_dict(): + await test_import_completion_data_async(request_type=dict) + + +def test_import_completion_data_field_headers(): + client = CompletionServiceClient( + 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 = import_config.ImportCompletionDataRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_completion_data(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_completion_data_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = import_config.ImportCompletionDataRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_completion_data(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'] + + +@pytest.mark.parametrize("request_type", [ + completion_service.CompleteQueryRequest, + dict, +]) +def test_complete_query_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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 = completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = completion_service.CompleteQueryResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.complete_query(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +def test_complete_query_rest_required_fields(request_type=completion_service.CompleteQueryRequest): + transport_class = transports.CompletionServiceRestTransport + + request_init = {} + request_init["catalog"] = "" + request_init["query"] = "" + 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 + assert "query" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).complete_query._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "query" in jsonified_request + assert jsonified_request["query"] == request_init["query"] + + jsonified_request["catalog"] = 'catalog_value' + jsonified_request["query"] = 'query_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).complete_query._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dataset", "device_type", "entity", "language_codes", "max_suggestions", "query", "visitor_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "catalog" in jsonified_request + assert jsonified_request["catalog"] == 'catalog_value' + assert "query" in jsonified_request + assert jsonified_request["query"] == 'query_value' + + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = completion_service.CompleteQueryResponse() + # 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 + + pb_return_value = completion_service.CompleteQueryResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.complete_query(request) + + expected_params = [ + ( + "query", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_complete_query_rest_unset_required_fields(): + transport = transports.CompletionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.complete_query._get_unset_required_fields({}) + assert set(unset_fields) == (set(("dataset", "deviceType", "entity", "languageCodes", "maxSuggestions", "query", "visitorId", )) & set(("catalog", "query", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_complete_query_rest_interceptors(null_interceptor): + transport = transports.CompletionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CompletionServiceRestInterceptor(), + ) + client = CompletionServiceClient(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.CompletionServiceRestInterceptor, "post_complete_query") as post, \ + mock.patch.object(transports.CompletionServiceRestInterceptor, "pre_complete_query") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = completion_service.CompleteQueryRequest.pb(completion_service.CompleteQueryRequest()) + 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 = completion_service.CompleteQueryResponse.to_json(completion_service.CompleteQueryResponse()) + + request = completion_service.CompleteQueryRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = completion_service.CompleteQueryResponse() + + client.complete_query(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_complete_query_rest_bad_request(transport: str = 'rest', request_type=completion_service.CompleteQueryRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.complete_query(request) + + +def test_complete_query_rest_error(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportCompletionDataRequest, + dict, +]) +def test_import_completion_data_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_completion_data(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_completion_data_rest_required_fields(request_type=import_config.ImportCompletionDataRequest): + transport_class = transports.CompletionServiceRestTransport + + 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_completion_data._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_completion_data._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 = CompletionServiceClient( + 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_completion_data(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_completion_data_rest_unset_required_fields(): + transport = transports.CompletionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_completion_data._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_completion_data_rest_interceptors(null_interceptor): + transport = transports.CompletionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CompletionServiceRestInterceptor(), + ) + client = CompletionServiceClient(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.CompletionServiceRestInterceptor, "post_import_completion_data") as post, \ + mock.patch.object(transports.CompletionServiceRestInterceptor, "pre_import_completion_data") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportCompletionDataRequest.pb(import_config.ImportCompletionDataRequest()) + 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 = import_config.ImportCompletionDataRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_completion_data(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_completion_data_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportCompletionDataRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.import_completion_data(request) + + +def test_import_completion_data_rest_error(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CompletionServiceClient( + 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 = CompletionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CompletionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CompletionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + transports.CompletionServiceRestTransport, +]) +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 = CompletionServiceClient.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 = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CompletionServiceGrpcTransport, + ) + +def test_completion_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_completion_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.completion_service.transports.CompletionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'complete_query', + 'import_completion_data', + 'get_operation', + 'list_operations', + ) + 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_completion_service_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.retail_v2.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_completion_service_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.retail_v2.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport() + adc.assert_called_once() + + +def test_completion_service_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) + CompletionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + ], +) +def test_completion_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + transports.CompletionServiceRestTransport, + ], +) +def test_completion_service_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.CompletionServiceGrpcTransport, grpc_helpers), + (transports.CompletionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_completion_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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_completion_service_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.CompletionServiceRestTransport ( + 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_completion_service_rest_lro_client(): + client = CompletionServiceClient( + 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_completion_service_host_no_port(transport_name): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_completion_service_host_with_port(transport_name): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_completion_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CompletionServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CompletionServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.complete_query._session + session2 = client2.transport.complete_query._session + assert session1 != session2 + session1 = client1.transport.import_completion_data._session + session2 = client2.transport.import_completion_data._session + assert session1 != session2 +def test_completion_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcTransport( + 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_completion_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcAsyncIOTransport( + 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.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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_completion_service_grpc_lro_client(): + client = CompletionServiceClient( + 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_completion_service_grpc_lro_async_client(): + client = CompletionServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CompletionServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = CompletionServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CompletionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = CompletionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = CompletionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = CompletionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CompletionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = CompletionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = CompletionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = CompletionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CompletionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = CompletionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.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.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CompletionServiceClient.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 = CompletionServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = CompletionServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = CompletionServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = CompletionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = CompletionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CompletionServiceClient( + 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 = CompletionServiceClient( + 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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_control_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_control_service.py new file mode 100644 index 00000000..0340b0f5 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_control_service.py @@ -0,0 +1,4300 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.control_service import ControlServiceAsyncClient +from google.cloud.retail_v2.services.control_service import ControlServiceClient +from google.cloud.retail_v2.services.control_service import pagers +from google.cloud.retail_v2.services.control_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import control +from google.cloud.retail_v2.types import control as gcr_control +from google.cloud.retail_v2.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_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 ControlServiceClient._get_default_mtls_endpoint(None) is None + assert ControlServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ControlServiceClient, "grpc"), + (ControlServiceAsyncClient, "grpc_asyncio"), + (ControlServiceClient, "rest"), +]) +def test_control_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ControlServiceGrpcTransport, "grpc"), + (transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ControlServiceRestTransport, "rest"), +]) +def test_control_service_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", [ + (ControlServiceClient, "grpc"), + (ControlServiceAsyncClient, "grpc_asyncio"), + (ControlServiceClient, "rest"), +]) +def test_control_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_control_service_client_get_transport_class(): + transport = ControlServiceClient.get_transport_class() + available_transports = [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceRestTransport, + ] + assert transport in available_transports + + transport = ControlServiceClient.get_transport_class("grpc") + assert transport == transports.ControlServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest"), +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +def test_control_service_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(ControlServiceClient, '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(ControlServiceClient, '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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", "true"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", "false"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", "true"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_control_service_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", [ + ControlServiceClient, ControlServiceAsyncClient +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +def test_control_service_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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest"), +]) +def test_control_service_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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", grpc_helpers), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", None), +]) +def test_control_service_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_control_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.control_service.transports.ControlServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ControlServiceClient( + 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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", grpc_helpers), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_control_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.CreateControlRequest, + dict, +]) +def test_create_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.create_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_create_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.create_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + +@pytest.mark.asyncio +async def test_create_control_async(transport: str = 'grpc_asyncio', request_type=control_service.CreateControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.create_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_create_control_async_from_dict(): + await test_create_control_async(request_type=dict) + + +def test_create_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.CreateControlRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + call.return_value = gcr_control.Control() + client.create_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.CreateControlRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + await client.create_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_control( + parent='parent_value', + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + control_id='control_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].control + mock_val = gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))) + assert arg == mock_val + arg = args[0].control_id + mock_val = 'control_id_value' + assert arg == mock_val + + +def test_create_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + control_id='control_id_value', + ) + +@pytest.mark.asyncio +async def test_create_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_control( + parent='parent_value', + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + control_id='control_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].control + mock_val = gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))) + assert arg == mock_val + arg = args[0].control_id + mock_val = 'control_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + control_id='control_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.DeleteControlRequest, + dict, +]) +def test_delete_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.delete_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + +@pytest.mark.asyncio +async def test_delete_control_async(transport: str = 'grpc_asyncio', request_type=control_service.DeleteControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_control_async_from_dict(): + await test_delete_control_async(request_type=dict) + + +def test_delete_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.DeleteControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__call__') as call: + call.return_value = None + client.delete_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.DeleteControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__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_control( + 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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__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_control( + 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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.UpdateControlRequest, + dict, +]) +def test_update_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.update_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_update_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.update_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + +@pytest.mark.asyncio +async def test_update_control_async(transport: str = 'grpc_asyncio', request_type=control_service.UpdateControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.update_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_update_control_async_from_dict(): + await test_update_control_async(request_type=dict) + + +def test_update_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.UpdateControlRequest() + + request.control.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + call.return_value = gcr_control.Control() + client.update_control(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', + 'control.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.UpdateControlRequest() + + request.control.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + await client.update_control(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', + 'control.name=name_value', + ) in kw['metadata'] + + +def test_update_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_control( + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + 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].control + mock_val = gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))) + 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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_control( + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + 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].control + mock_val = gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))) + 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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.GetControlRequest, + dict, +]) +def test_get_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.get_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_get_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.get_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + +@pytest.mark.asyncio +async def test_get_control_async(transport: str = 'grpc_asyncio', request_type=control_service.GetControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.get_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_get_control_async_from_dict(): + await test_get_control_async(request_type=dict) + + +def test_get_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.GetControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + call.return_value = control.Control() + client.get_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.GetControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control.Control()) + await client.get_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_control( + 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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_control( + 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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.ListControlsRequest, + dict, +]) +def test_list_controls(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_controls(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_controls_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 = ControlServiceClient( + 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_controls), + '__call__') as call: + client.list_controls() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + +@pytest.mark.asyncio +async def test_list_controls_async(transport: str = 'grpc_asyncio', request_type=control_service.ListControlsRequest): + client = ControlServiceAsyncClient( + 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_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_controls(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_controls_async_from_dict(): + await test_list_controls_async(request_type=dict) + + +def test_list_controls_field_headers(): + client = ControlServiceClient( + 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 = control_service.ListControlsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + call.return_value = control_service.ListControlsResponse() + client.list_controls(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_controls_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.ListControlsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse()) + await client.list_controls(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_controls_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_controls( + 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_controls_flattened_error(): + client = ControlServiceClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_controls_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_controls( + 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_controls_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + + +def test_list_controls_pager(transport_name: str = "grpc"): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_controls(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, control.Control) + for i in results) +def test_list_controls_pages(transport_name: str = "grpc"): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + pages = list(client.list_controls(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_controls_async_pager(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_controls(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, control.Control) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_controls_async_pages(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + 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_controls(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", [ + control_service.CreateControlRequest, + dict, +]) +def test_create_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["control"] = {'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'name_value', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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 = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_create_control_rest_required_fields(request_type=control_service.CreateControlRequest): + transport_class = transports.ControlServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["control_id"] = "" + 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 + assert "controlId" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == request_init["control_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_control._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("control_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' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_control.Control() + # 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 + + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_control(request) + + expected_params = [ + ( + "controlId", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(("controlId", )) & set(("parent", "control", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_create_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_create_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.CreateControlRequest.pb(control_service.CreateControlRequest()) + 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 = gcr_control.Control.to_json(gcr_control.Control()) + + request = control_service.CreateControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_control.Control() + + client.create_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_control_rest_bad_request(transport: str = 'rest', request_type=control_service.CreateControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["control"] = {'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'name_value', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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_control(request) + + +def test_create_control_rest_flattened(): + client = ControlServiceClient( + 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 = gcr_control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + control_id='control_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_control(**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/v2/{parent=projects/*/locations/*/catalogs/*}/controls" % client.transport._host, args[1]) + + +def test_create_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + control_id='control_id_value', + ) + + +def test_create_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.DeleteControlRequest, + dict, +]) +def test_delete_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_control_rest_required_fields(request_type=control_service.DeleteControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + 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_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "pre_delete_control") as pre: + pre.assert_not_called() + pb_message = control_service.DeleteControlRequest.pb(control_service.DeleteControlRequest()) + 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 = control_service.DeleteControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_control_rest_bad_request(transport: str = 'rest', request_type=control_service.DeleteControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + +def test_delete_control_rest_flattened(): + client = ControlServiceClient( + 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/catalogs/sample3/controls/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_control(**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/v2/{name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_delete_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + + +def test_delete_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.UpdateControlRequest, + dict, +]) +def test_update_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + request_init["control"] = {'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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 = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_update_control_rest_required_fields(request_type=control_service.UpdateControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_control.Control() + # 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 + + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("control", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_update_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_update_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.UpdateControlRequest.pb(control_service.UpdateControlRequest()) + 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 = gcr_control.Control.to_json(gcr_control.Control()) + + request = control_service.UpdateControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_control.Control() + + client.update_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_control_rest_bad_request(transport: str = 'rest', request_type=control_service.UpdateControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + request_init["control"] = {'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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_control(request) + + +def test_update_control_rest_flattened(): + client = ControlServiceClient( + 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 = gcr_control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + 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 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_control(**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/v2/{control.name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_update_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(rule=common.Rule(boost_action=common.Rule.BoostAction(boost=0.551))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.GetControlRequest, + dict, +]) +def test_get_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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 = control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_get_control_rest_required_fields(request_type=control_service.GetControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = control.Control() + # 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 + + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_get_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_get_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.GetControlRequest.pb(control_service.GetControlRequest()) + 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 = control.Control.to_json(control.Control()) + + request = control_service.GetControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = control.Control() + + client.get_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_control_rest_bad_request(transport: str = 'rest', request_type=control_service.GetControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + +def test_get_control_rest_flattened(): + client = ControlServiceClient( + 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 = control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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 + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_control(**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/v2/{name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_get_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + + +def test_get_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.ListControlsRequest, + dict, +]) +def test_list_controls_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = control_service.ListControlsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_controls(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_controls_rest_required_fields(request_type=control_service.ListControlsRequest): + transport_class = transports.ControlServiceRestTransport + + 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_controls._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_controls._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("filter", "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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = control_service.ListControlsResponse() + # 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 + + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_controls(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_controls_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_controls._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_controls_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_list_controls") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_list_controls") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.ListControlsRequest.pb(control_service.ListControlsRequest()) + 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 = control_service.ListControlsResponse.to_json(control_service.ListControlsResponse()) + + request = control_service.ListControlsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = control_service.ListControlsResponse() + + client.list_controls(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_controls_rest_bad_request(transport: str = 'rest', request_type=control_service.ListControlsRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_controls(request) + + +def test_list_controls_rest_flattened(): + client = ControlServiceClient( + 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 = control_service.ListControlsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_controls(**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/v2/{parent=projects/*/locations/*/catalogs/*}/controls" % client.transport._host, args[1]) + + +def test_list_controls_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + + +def test_list_controls_rest_pager(transport: str = 'rest'): + client = ControlServiceClient( + 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 = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(control_service.ListControlsResponse.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/catalogs/sample3'} + + pager = client.list_controls(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, control.Control) + for i in results) + + pages = list(client.list_controls(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ControlServiceClient( + 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 = ControlServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ControlServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ControlServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + transports.ControlServiceRestTransport, +]) +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 = ControlServiceClient.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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ControlServiceGrpcTransport, + ) + +def test_control_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ControlServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_control_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.control_service.transports.ControlServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ControlServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_control', + 'delete_control', + 'update_control', + 'get_control', + 'list_controls', + 'get_operation', + 'list_operations', + ) + 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_control_service_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.retail_v2.services.control_service.transports.ControlServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ControlServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_control_service_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.retail_v2.services.control_service.transports.ControlServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ControlServiceTransport() + adc.assert_called_once() + + +def test_control_service_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) + ControlServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + ], +) +def test_control_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + transports.ControlServiceRestTransport, + ], +) +def test_control_service_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.ControlServiceGrpcTransport, grpc_helpers), + (transports.ControlServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_control_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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_control_service_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.ControlServiceRestTransport ( + 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_control_service_host_no_port(transport_name): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_control_service_host_with_port(transport_name): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_control_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ControlServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ControlServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_control._session + session2 = client2.transport.create_control._session + assert session1 != session2 + session1 = client1.transport.delete_control._session + session2 = client2.transport.delete_control._session + assert session1 != session2 + session1 = client1.transport.update_control._session + session2 = client2.transport.update_control._session + assert session1 != session2 + session1 = client1.transport.get_control._session + session2 = client2.transport.get_control._session + assert session1 != session2 + session1 = client1.transport.list_controls._session + session2 = client2.transport.list_controls._session + assert session1 != session2 +def test_control_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ControlServiceGrpcTransport( + 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_control_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ControlServiceGrpcAsyncIOTransport( + 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.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ControlServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ControlServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_control_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + control = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/controls/{control}".format(project=project, location=location, catalog=catalog, control=control, ) + actual = ControlServiceClient.control_path(project, location, catalog, control) + assert expected == actual + + +def test_parse_control_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "control": "clam", + } + path = ControlServiceClient.control_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_control_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ControlServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ControlServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ControlServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ControlServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ControlServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ControlServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ControlServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ControlServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ControlServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ControlServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.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.ControlServiceTransport, '_prep_wrapped_messages') as prep: + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ControlServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ControlServiceClient.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 = ControlServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ControlServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ControlServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ControlServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ControlServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ControlServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ControlServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ControlServiceClient( + 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 = ControlServiceClient( + 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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_model_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_model_service.py new file mode 100644 index 00000000..5825949e --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_model_service.py @@ -0,0 +1,5874 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.model_service import ModelServiceAsyncClient +from google.cloud.retail_v2.services.model_service import ModelServiceClient +from google.cloud.retail_v2.services.model_service import pagers +from google.cloud.retail_v2.services.model_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import model +from google.cloud.retail_v2.types import model as gcr_model +from google.cloud.retail_v2.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_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 ModelServiceClient._get_default_mtls_endpoint(None) is None + assert ModelServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), +]) +def test_model_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ModelServiceGrpcTransport, "grpc"), + (transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ModelServiceRestTransport, "rest"), +]) +def test_model_service_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", [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), +]) +def test_model_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_model_service_client_get_transport_class(): + transport = ModelServiceClient.get_transport_class() + available_transports = [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceRestTransport, + ] + assert transport in available_transports + + transport = ModelServiceClient.get_transport_class("grpc") + assert transport == transports.ModelServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +def test_model_service_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(ModelServiceClient, '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(ModelServiceClient, '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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "true"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "false"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "true"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_model_service_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", [ + ModelServiceClient, ModelServiceAsyncClient +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +def test_model_service_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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), +]) +def test_model_service_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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", grpc_helpers), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", None), +]) +def test_model_service_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_model_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.model_service.transports.ModelServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ModelServiceClient( + 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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", grpc_helpers), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_model_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.CreateModelRequest, + dict, +]) +def test_create_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.create_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + +@pytest.mark.asyncio +async def test_create_model_async(transport: str = 'grpc_asyncio', request_type=model_service.CreateModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__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.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_model_async_from_dict(): + await test_create_model_async(request_type=dict) + + +def test_create_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.CreateModelRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.create_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.CreateModelRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.create_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__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.create_model( + parent='parent_value', + model=gcr_model.Model(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].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].model + mock_val = gcr_model.Model(name='name_value') + assert arg == mock_val + + +def test_create_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(name='name_value'), + ) + +@pytest.mark.asyncio +async def test_create_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__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.create_model( + parent='parent_value', + model=gcr_model.Model(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].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].model + mock_val = gcr_model.Model(name='name_value') + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(name='name_value'), + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.GetModelRequest, + dict, +]) +def test_get_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_get_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.get_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + +@pytest.mark.asyncio +async def test_get_model_async(transport: str = 'grpc_asyncio', request_type=model_service.GetModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + +def test_get_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.GetModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + call.return_value = model.Model() + client.get_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.GetModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.get_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_model( + 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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_model( + 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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.PauseModelRequest, + dict, +]) +def test_pause_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_pause_model_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 = ModelServiceClient( + 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.pause_model), + '__call__') as call: + client.pause_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + +@pytest.mark.asyncio +async def test_pause_model_async(transport: str = 'grpc_asyncio', request_type=model_service.PauseModelRequest): + client = ModelServiceAsyncClient( + 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.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_pause_model_async_from_dict(): + await test_pause_model_async(request_type=dict) + + +def test_pause_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.PauseModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + call.return_value = model.Model() + client.pause_model(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_pause_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.PauseModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.pause_model(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_pause_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.pause_model( + 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_pause_model_flattened_error(): + client = ModelServiceClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_pause_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.pause_model( + 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_pause_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ResumeModelRequest, + dict, +]) +def test_resume_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_resume_model_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 = ModelServiceClient( + 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.resume_model), + '__call__') as call: + client.resume_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + +@pytest.mark.asyncio +async def test_resume_model_async(transport: str = 'grpc_asyncio', request_type=model_service.ResumeModelRequest): + client = ModelServiceAsyncClient( + 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.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_resume_model_async_from_dict(): + await test_resume_model_async(request_type=dict) + + +def test_resume_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.ResumeModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + call.return_value = model.Model() + client.resume_model(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_resume_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.ResumeModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.resume_model(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_resume_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.resume_model( + 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_resume_model_flattened_error(): + client = ModelServiceClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_resume_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.resume_model( + 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_resume_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.DeleteModelRequest, + dict, +]) +def test_delete_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.delete_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + +@pytest.mark.asyncio +async def test_delete_model_async(transport: str = 'grpc_asyncio', request_type=model_service.DeleteModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_model_async_from_dict(): + await test_delete_model_async(request_type=dict) + + +def test_delete_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.DeleteModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__call__') as call: + call.return_value = None + client.delete_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.DeleteModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__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_model( + 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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__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_model( + 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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ListModelsRequest, + dict, +]) +def test_list_models(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_models_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 = ModelServiceClient( + 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_models), + '__call__') as call: + client.list_models() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + +@pytest.mark.asyncio +async def test_list_models_async(transport: str = 'grpc_asyncio', request_type=model_service.ListModelsRequest): + client = ModelServiceAsyncClient( + 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_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_models_async_from_dict(): + await test_list_models_async(request_type=dict) + + +def test_list_models_field_headers(): + client = ModelServiceClient( + 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 = model_service.ListModelsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + call.return_value = model_service.ListModelsResponse() + client.list_models(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_models_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.ListModelsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse()) + await client.list_models(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_models_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_models( + 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_models_flattened_error(): + client = ModelServiceClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_models_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_models( + 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_models_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + + +def test_list_models_pager(transport_name: str = "grpc"): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_models(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) + for i in results) +def test_list_models_pages(transport_name: str = "grpc"): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + pages = list(client.list_models(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_models_async_pager(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_models(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, model.Model) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_models_async_pages(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + 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_models(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", [ + model_service.UpdateModelRequest, + dict, +]) +def test_update_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_update_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.update_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + +@pytest.mark.asyncio +async def test_update_model_async(transport: str = 'grpc_asyncio', request_type=model_service.UpdateModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_update_model_async_from_dict(): + await test_update_model_async(request_type=dict) + + +def test_update_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.UpdateModelRequest() + + request.model.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + call.return_value = gcr_model.Model() + client.update_model(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', + 'model.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.UpdateModelRequest() + + request.model.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + await client.update_model(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', + 'model.name=name_value', + ) in kw['metadata'] + + +def test_update_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_model( + model=gcr_model.Model(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].model + mock_val = gcr_model.Model(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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_model( + model=gcr_model.Model(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].model + mock_val = gcr_model.Model(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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.TuneModelRequest, + dict, +]) +def test_tune_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.tune_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_tune_model_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 = ModelServiceClient( + 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.tune_model), + '__call__') as call: + client.tune_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + +@pytest.mark.asyncio +async def test_tune_model_async(transport: str = 'grpc_asyncio', request_type=model_service.TuneModelRequest): + client = ModelServiceAsyncClient( + 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.tune_model), + '__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.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_tune_model_async_from_dict(): + await test_tune_model_async(request_type=dict) + + +def test_tune_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.TuneModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.tune_model(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_tune_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.TuneModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.tune_model(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_tune_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__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.tune_model( + 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_tune_model_flattened_error(): + client = ModelServiceClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_tune_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__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.tune_model( + 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_tune_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.CreateModelRequest, + dict, +]) +def test_create_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["model"] = {'name': 'name_value', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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.create_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_model_rest_required_fields(request_type=model_service.CreateModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dry_run", )) + 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 = ModelServiceClient( + 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.create_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(("dryRun", )) & set(("parent", "model", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_create_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_create_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.CreateModelRequest.pb(model_service.CreateModelRequest()) + 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 = model_service.CreateModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_model_rest_bad_request(transport: str = 'rest', request_type=model_service.CreateModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["model"] = {'name': 'name_value', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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_model(request) + + +def test_create_model_rest_flattened(): + client = ModelServiceClient( + 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/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + model=gcr_model.Model(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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_model(**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/v2/{parent=projects/*/locations/*/catalogs/*}/models" % client.transport._host, args[1]) + + +def test_create_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(name='name_value'), + ) + + +def test_create_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.GetModelRequest, + dict, +]) +def test_get_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_get_model_rest_required_fields(request_type=model_service.GetModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_get_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_get_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.GetModelRequest.pb(model_service.GetModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.GetModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.get_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_model_rest_bad_request(transport: str = 'rest', request_type=model_service.GetModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + +def test_get_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_model(**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/v2/{name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_get_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + + +def test_get_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.PauseModelRequest, + dict, +]) +def test_pause_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.pause_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_pause_model_rest_required_fields(request_type=model_service.PauseModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).pause_model._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()).pause_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.pause_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_pause_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.pause_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_pause_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_pause_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_pause_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.PauseModelRequest.pb(model_service.PauseModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.PauseModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.pause_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_pause_model_rest_bad_request(transport: str = 'rest', request_type=model_service.PauseModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.pause_model(request) + + +def test_pause_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.pause_model(**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/v2/{name=projects/*/locations/*/catalogs/*/models/*}:pause" % client.transport._host, args[1]) + + +def test_pause_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + + +def test_pause_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ResumeModelRequest, + dict, +]) +def test_resume_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.resume_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_resume_model_rest_required_fields(request_type=model_service.ResumeModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).resume_model._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()).resume_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.resume_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_resume_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.resume_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_resume_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_resume_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_resume_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ResumeModelRequest.pb(model_service.ResumeModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.ResumeModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.resume_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_resume_model_rest_bad_request(transport: str = 'rest', request_type=model_service.ResumeModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.resume_model(request) + + +def test_resume_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.resume_model(**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/v2/{name=projects/*/locations/*/catalogs/*/models/*}:resume" % client.transport._host, args[1]) + + +def test_resume_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + + +def test_resume_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.DeleteModelRequest, + dict, +]) +def test_delete_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_rest_required_fields(request_type=model_service.DeleteModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + 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_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "pre_delete_model") as pre: + pre.assert_not_called() + pb_message = model_service.DeleteModelRequest.pb(model_service.DeleteModelRequest()) + 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 = model_service.DeleteModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_model_rest_bad_request(transport: str = 'rest', request_type=model_service.DeleteModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + +def test_delete_model_rest_flattened(): + client = ModelServiceClient( + 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/catalogs/sample3/models/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_model(**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/v2/{name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_delete_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + + +def test_delete_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ListModelsRequest, + dict, +]) +def test_list_models_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = model_service.ListModelsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_models(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_models_rest_required_fields(request_type=model_service.ListModelsRequest): + transport_class = transports.ModelServiceRestTransport + + 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_models._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_models._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model_service.ListModelsResponse() + # 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 + + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_models(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_models_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_models._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_models_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_list_models") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_list_models") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ListModelsRequest.pb(model_service.ListModelsRequest()) + 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 = model_service.ListModelsResponse.to_json(model_service.ListModelsResponse()) + + request = model_service.ListModelsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model_service.ListModelsResponse() + + client.list_models(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_models_rest_bad_request(transport: str = 'rest', request_type=model_service.ListModelsRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_models(request) + + +def test_list_models_rest_flattened(): + client = ModelServiceClient( + 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 = model_service.ListModelsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_models(**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/v2/{parent=projects/*/locations/*/catalogs/*}/models" % client.transport._host, args[1]) + + +def test_list_models_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + + +def test_list_models_rest_pager(transport: str = 'rest'): + client = ModelServiceClient( + 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 = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(model_service.ListModelsResponse.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/catalogs/sample3'} + + pager = client.list_models(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) + for i in results) + + pages = list(client.list_models(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", [ + model_service.UpdateModelRequest, + dict, +]) +def test_update_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + request_init["model"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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 = gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_update_model_rest_required_fields(request_type=model_service.UpdateModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_model.Model() + # 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 + + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("model", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_update_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_update_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.UpdateModelRequest.pb(model_service.UpdateModelRequest()) + 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 = gcr_model.Model.to_json(gcr_model.Model()) + + request = model_service.UpdateModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_model.Model() + + client.update_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_model_rest_bad_request(transport: str = 'rest', request_type=model_service.UpdateModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + request_init["model"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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_model(request) + + +def test_update_model_rest_flattened(): + client = ModelServiceClient( + 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 = gcr_model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + model=gcr_model.Model(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 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_model(**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/v2/{model.name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_update_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.TuneModelRequest, + dict, +]) +def test_tune_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = 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.tune_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_tune_model_rest_required_fields(request_type=model_service.TuneModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).tune_model._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()).tune_model._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 = ModelServiceClient( + 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.tune_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_tune_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.tune_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_tune_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_tune_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_tune_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.TuneModelRequest.pb(model_service.TuneModelRequest()) + 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 = model_service.TuneModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.tune_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_tune_model_rest_bad_request(transport: str = 'rest', request_type=model_service.TuneModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.tune_model(request) + + +def test_tune_model_rest_flattened(): + client = ModelServiceClient( + 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 = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.tune_model(**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/v2/{name=projects/*/locations/*/catalogs/*/models/*}:tune" % client.transport._host, args[1]) + + +def test_tune_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + + +def test_tune_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ModelServiceClient( + 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 = ModelServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ModelServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ModelServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, +]) +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 = ModelServiceClient.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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ModelServiceGrpcTransport, + ) + +def test_model_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_model_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.model_service.transports.ModelServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_model', + 'get_model', + 'pause_model', + 'resume_model', + 'delete_model', + 'list_models', + 'update_model', + 'tune_model', + 'get_operation', + 'list_operations', + ) + 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_model_service_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.retail_v2.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_model_service_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.retail_v2.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport() + adc.assert_called_once() + + +def test_model_service_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) + ModelServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + ], +) +def test_model_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, + ], +) +def test_model_service_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.ModelServiceGrpcTransport, grpc_helpers), + (transports.ModelServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_model_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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_model_service_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.ModelServiceRestTransport ( + 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_model_service_rest_lro_client(): + client = ModelServiceClient( + 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_model_service_host_no_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_model_service_host_with_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_model_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ModelServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ModelServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_model._session + session2 = client2.transport.create_model._session + assert session1 != session2 + session1 = client1.transport.get_model._session + session2 = client2.transport.get_model._session + assert session1 != session2 + session1 = client1.transport.pause_model._session + session2 = client2.transport.pause_model._session + assert session1 != session2 + session1 = client1.transport.resume_model._session + session2 = client2.transport.resume_model._session + assert session1 != session2 + session1 = client1.transport.delete_model._session + session2 = client2.transport.delete_model._session + assert session1 != session2 + session1 = client1.transport.list_models._session + session2 = client2.transport.list_models._session + assert session1 != session2 + session1 = client1.transport.update_model._session + session2 = client2.transport.update_model._session + assert session1 != session2 + session1 = client1.transport.tune_model._session + session2 = client2.transport.tune_model._session + assert session1 != session2 +def test_model_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcTransport( + 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_model_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcAsyncIOTransport( + 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.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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_model_service_grpc_lro_client(): + client = ModelServiceClient( + 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_model_service_grpc_lro_async_client(): + client = ModelServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ModelServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ModelServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_model_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + model = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format(project=project, location=location, catalog=catalog, model=model, ) + actual = ModelServiceClient.model_path(project, location, catalog, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "model": "clam", + } + path = ModelServiceClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_model_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ModelServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ModelServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ModelServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ModelServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ModelServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ModelServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ModelServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ModelServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ModelServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ModelServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.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.ModelServiceTransport, '_prep_wrapped_messages') as prep: + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ModelServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ModelServiceClient.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 = ModelServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ModelServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ModelServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ModelServiceClient( + 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 = ModelServiceClient( + 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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_prediction_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py new file mode 100644 index 00000000..b294a277 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_prediction_service.py @@ -0,0 +1,1931 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.prediction_service import PredictionServiceAsyncClient +from google.cloud.retail_v2.services.prediction_service import PredictionServiceClient +from google.cloud.retail_v2.services.prediction_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import prediction_service +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import promotion +from google.cloud.retail_v2.types import user_event +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_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 PredictionServiceClient._get_default_mtls_endpoint(None) is None + assert PredictionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (PredictionServiceClient, "grpc"), + (PredictionServiceAsyncClient, "grpc_asyncio"), + (PredictionServiceClient, "rest"), +]) +def test_prediction_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.PredictionServiceGrpcTransport, "grpc"), + (transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.PredictionServiceRestTransport, "rest"), +]) +def test_prediction_service_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", [ + (PredictionServiceClient, "grpc"), + (PredictionServiceAsyncClient, "grpc_asyncio"), + (PredictionServiceClient, "rest"), +]) +def test_prediction_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_prediction_service_client_get_transport_class(): + transport = PredictionServiceClient.get_transport_class() + available_transports = [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceRestTransport, + ] + assert transport in available_transports + + transport = PredictionServiceClient.get_transport_class("grpc") + assert transport == transports.PredictionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_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(PredictionServiceClient, '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(PredictionServiceClient, '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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "true"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "false"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", "true"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_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", [ + PredictionServiceClient, PredictionServiceAsyncClient +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest"), +]) +def test_prediction_service_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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", grpc_helpers), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", None), +]) +def test_prediction_service_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_prediction_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = PredictionServiceClient( + 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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", grpc_helpers), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_prediction_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + prediction_service.PredictRequest, + dict, +]) +def test_predict(request_type, transport: str = 'grpc'): + client = PredictionServiceClient( + 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + ) + response = client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +def test_predict_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 = PredictionServiceClient( + 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.predict), + '__call__') as call: + client.predict() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + +@pytest.mark.asyncio +async def test_predict_async(transport: str = 'grpc_asyncio', request_type=prediction_service.PredictRequest): + client = PredictionServiceAsyncClient( + 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + )) + response = await client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +@pytest.mark.asyncio +async def test_predict_async_from_dict(): + await test_predict_async(request_type=dict) + + +def test_predict_field_headers(): + client = PredictionServiceClient( + 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 = prediction_service.PredictRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = prediction_service.PredictResponse() + client.predict(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_predict_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = prediction_service.PredictRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse()) + await client.predict(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + prediction_service.PredictRequest, + dict, +]) +def test_predict_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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 = prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = prediction_service.PredictResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.predict(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +def test_predict_rest_required_fields(request_type=prediction_service.PredictRequest): + transport_class = transports.PredictionServiceRestTransport + + request_init = {} + request_init["placement"] = "" + 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()).predict._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["placement"] = 'placement_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).predict._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "placement" in jsonified_request + assert jsonified_request["placement"] == 'placement_value' + + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = prediction_service.PredictResponse() + # 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 + + pb_return_value = prediction_service.PredictResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.predict(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_predict_rest_unset_required_fields(): + transport = transports.PredictionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.predict._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("placement", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_predict_rest_interceptors(null_interceptor): + transport = transports.PredictionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PredictionServiceRestInterceptor(), + ) + client = PredictionServiceClient(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.PredictionServiceRestInterceptor, "post_predict") as post, \ + mock.patch.object(transports.PredictionServiceRestInterceptor, "pre_predict") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = prediction_service.PredictRequest.pb(prediction_service.PredictRequest()) + 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 = prediction_service.PredictResponse.to_json(prediction_service.PredictResponse()) + + request = prediction_service.PredictRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = prediction_service.PredictResponse() + + client.predict(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_predict_rest_bad_request(transport: str = 'rest', request_type=prediction_service.PredictRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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.predict(request) + + +def test_predict_rest_error(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PredictionServiceClient( + 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 = PredictionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PredictionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + transports.PredictionServiceRestTransport, +]) +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 = PredictionServiceClient.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 = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.PredictionServiceGrpcTransport, + ) + +def test_prediction_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_prediction_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.prediction_service.transports.PredictionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'predict', + 'get_operation', + 'list_operations', + ) + 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_prediction_service_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.retail_v2.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_prediction_service_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.retail_v2.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + +def test_prediction_service_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) + PredictionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_prediction_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + transports.PredictionServiceRestTransport, + ], +) +def test_prediction_service_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.PredictionServiceGrpcTransport, grpc_helpers), + (transports.PredictionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_prediction_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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_prediction_service_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.PredictionServiceRestTransport ( + 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_prediction_service_host_no_port(transport_name): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_prediction_service_host_with_port(transport_name): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_prediction_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = PredictionServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = PredictionServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.predict._session + session2 = client2.transport.predict._session + assert session1 != session2 +def test_prediction_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcTransport( + 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_prediction_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcAsyncIOTransport( + 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.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + product = "oyster" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = PredictionServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "catalog": "mussel", + "branch": "winkle", + "product": "nautilus", + } + path = PredictionServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = PredictionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = PredictionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = PredictionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = PredictionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = PredictionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = PredictionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = PredictionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = PredictionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = PredictionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = PredictionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.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.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = PredictionServiceClient.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 = PredictionServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = PredictionServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = PredictionServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = PredictionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = PredictionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = PredictionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = PredictionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = PredictionServiceClient( + 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 = PredictionServiceClient( + 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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_product_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py new file mode 100644 index 00000000..bf6c69ae --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_product_service.py @@ -0,0 +1,7266 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.product_service import ProductServiceAsyncClient +from google.cloud.retail_v2.services.product_service import ProductServiceClient +from google.cloud.retail_v2.services.product_service import pagers +from google.cloud.retail_v2.services.product_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import product as gcr_product +from google.cloud.retail_v2.types import product_service +from google.cloud.retail_v2.types import promotion +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.type import date_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 ProductServiceClient._get_default_mtls_endpoint(None) is None + assert ProductServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductServiceClient, "grpc"), + (ProductServiceAsyncClient, "grpc_asyncio"), + (ProductServiceClient, "rest"), +]) +def test_product_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ProductServiceGrpcTransport, "grpc"), + (transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ProductServiceRestTransport, "rest"), +]) +def test_product_service_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", [ + (ProductServiceClient, "grpc"), + (ProductServiceAsyncClient, "grpc_asyncio"), + (ProductServiceClient, "rest"), +]) +def test_product_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_product_service_client_get_transport_class(): + transport = ProductServiceClient.get_transport_class() + available_transports = [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceRestTransport, + ] + assert transport in available_transports + + transport = ProductServiceClient.get_transport_class("grpc") + assert transport == transports.ProductServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_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(ProductServiceClient, '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(ProductServiceClient, '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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "true"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "false"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", "true"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_product_service_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", [ + ProductServiceClient, ProductServiceAsyncClient +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest"), +]) +def test_product_service_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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", grpc_helpers), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", None), +]) +def test_product_service_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_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ProductServiceClient( + 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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", grpc_helpers), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_product_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.CreateProductRequest, + dict, +]) +def test_create_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.CreateProductRequest() + +@pytest.mark.asyncio +async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_service.CreateProductRequest): + client = ProductServiceAsyncClient( + 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(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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 = gcr_product.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 = ProductServiceAsyncClient( + 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_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(gcr_product.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 = ProductServiceClient( + 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 = gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceAsyncClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.GetProductRequest, + dict, +]) +def test_get_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.GetProductRequest() + +@pytest.mark.asyncio +async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_service.GetProductRequest): + client = ProductServiceAsyncClient( + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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.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 = ProductServiceAsyncClient( + 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_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.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 = ProductServiceClient( + 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.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 = ProductServiceClient( + 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_service.GetProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_flattened_async(): + client = ProductServiceAsyncClient( + 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.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product.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 = ProductServiceAsyncClient( + 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_service.GetProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.ListProductsRequest, + dict, +]) +def test_list_products(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_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_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 = ProductServiceClient( + 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_service.ListProductsRequest() + +@pytest.mark.asyncio +async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_service.ListProductsRequest): + client = ProductServiceAsyncClient( + 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_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_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 = ProductServiceClient( + 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_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_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 = ProductServiceAsyncClient( + 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_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_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 = ProductServiceClient( + 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_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 = ProductServiceClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_products_flattened_async(): + client = ProductServiceAsyncClient( + 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_service.ListProductsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_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 = ProductServiceAsyncClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_pager(transport_name: str = "grpc"): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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.Product) + for i in results) +def test_list_products_pages(transport_name: str = "grpc"): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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 = ProductServiceAsyncClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_async_pages(): + client = ProductServiceAsyncClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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_service.UpdateProductRequest, + dict, +]) +def test_update_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.UpdateProductRequest() + +@pytest.mark.asyncio +async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_service.UpdateProductRequest): + client = ProductServiceAsyncClient( + 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(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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 = gcr_product.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 = ProductServiceAsyncClient( + 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_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(gcr_product.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 = ProductServiceClient( + 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 = gcr_product.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceAsyncClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.DeleteProductRequest, + dict, +]) +def test_delete_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_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 = ProductServiceClient( + 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_service.DeleteProductRequest() + +@pytest.mark.asyncio +async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_service.DeleteProductRequest): + client = ProductServiceAsyncClient( + 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_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 = ProductServiceClient( + 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_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 = ProductServiceAsyncClient( + 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_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 = ProductServiceClient( + 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 = ProductServiceClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = ProductServiceAsyncClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportProductsRequest, + dict, +]) +def test_import_products(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_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] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_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 = ProductServiceClient( + 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_products), + '__call__') as call: + client.import_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + +@pytest.mark.asyncio +async def test_import_products_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportProductsRequest): + client = ProductServiceAsyncClient( + 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_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.import_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_products_async_from_dict(): + await test_import_products_async(request_type=dict) + + +def test_import_products_field_headers(): + client = ProductServiceClient( + 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 = import_config.ImportProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_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_import_products_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = import_config.ImportProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_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'] + + +@pytest.mark.parametrize("request_type", [ + product_service.SetInventoryRequest, + dict, +]) +def test_set_inventory(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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.set_inventory), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.set_inventory(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_service.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_set_inventory_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 = ProductServiceClient( + 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.set_inventory), + '__call__') as call: + client.set_inventory() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.SetInventoryRequest() + +@pytest.mark.asyncio +async def test_set_inventory_async(transport: str = 'grpc_asyncio', request_type=product_service.SetInventoryRequest): + client = ProductServiceAsyncClient( + 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.set_inventory), + '__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.set_inventory(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_set_inventory_async_from_dict(): + await test_set_inventory_async(request_type=dict) + + +def test_set_inventory_field_headers(): + client = ProductServiceClient( + 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_service.SetInventoryRequest() + + request.inventory.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.set_inventory(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', + 'inventory.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_inventory_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.SetInventoryRequest() + + request.inventory.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.set_inventory(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', + 'inventory.name=name_value', + ) in kw['metadata'] + + +def test_set_inventory_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_set_inventory_flattened_error(): + client = ProductServiceClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_set_inventory_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_set_inventory_flattened_error_async(): + client = ProductServiceAsyncClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddFulfillmentPlacesRequest, + dict, +]) +def test_add_fulfillment_places(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.add_fulfillment_places(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_service.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_add_fulfillment_places_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 = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + client.add_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddFulfillmentPlacesRequest() + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.AddFulfillmentPlacesRequest): + client = ProductServiceAsyncClient( + 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_fulfillment_places), + '__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.add_fulfillment_places(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async_from_dict(): + await test_add_fulfillment_places_async(request_type=dict) + + +def test_add_fulfillment_places_field_headers(): + client = ProductServiceClient( + 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_service.AddFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.add_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.AddFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.add_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +def test_add_fulfillment_places_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__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.add_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_fulfillment_places_flattened_error(): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_fulfillment_places_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__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.add_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_fulfillment_places_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveFulfillmentPlacesRequest, + dict, +]) +def test_remove_fulfillment_places(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.remove_fulfillment_places(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_service.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_remove_fulfillment_places_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 = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + client.remove_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveFulfillmentPlacesRequest() + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveFulfillmentPlacesRequest): + client = ProductServiceAsyncClient( + 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_fulfillment_places), + '__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.remove_fulfillment_places(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async_from_dict(): + await test_remove_fulfillment_places_async(request_type=dict) + + +def test_remove_fulfillment_places_field_headers(): + client = ProductServiceClient( + 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_service.RemoveFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.remove_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.RemoveFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.remove_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +def test_remove_fulfillment_places_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__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.remove_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_fulfillment_places_flattened_error(): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__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.remove_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddLocalInventoriesRequest, + dict, +]) +def test_add_local_inventories(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.add_local_inventories(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_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_add_local_inventories_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 = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + client.add_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + +@pytest.mark.asyncio +async def test_add_local_inventories_async(transport: str = 'grpc_asyncio', request_type=product_service.AddLocalInventoriesRequest): + client = ProductServiceAsyncClient( + 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_local_inventories), + '__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.add_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_local_inventories_async_from_dict(): + await test_add_local_inventories_async(request_type=dict) + + +def test_add_local_inventories_field_headers(): + client = ProductServiceClient( + 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_service.AddLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.add_local_inventories(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.AddLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.add_local_inventories(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=product_value', + ) in kw['metadata'] + + +def test_add_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__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.add_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_local_inventories_flattened_error(): + client = ProductServiceClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__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.add_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveLocalInventoriesRequest, + dict, +]) +def test_remove_local_inventories(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.remove_local_inventories(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_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_remove_local_inventories_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 = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + client.remove_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + +@pytest.mark.asyncio +async def test_remove_local_inventories_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveLocalInventoriesRequest): + client = ProductServiceAsyncClient( + 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_local_inventories), + '__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.remove_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_local_inventories_async_from_dict(): + await test_remove_local_inventories_async(request_type=dict) + + +def test_remove_local_inventories_field_headers(): + client = ProductServiceClient( + 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_service.RemoveLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.remove_local_inventories(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.RemoveLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.remove_local_inventories(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=product_value', + ) in kw['metadata'] + + +def test_remove_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__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.remove_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_local_inventories_flattened_error(): + client = ProductServiceClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__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.remove_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.CreateProductRequest, + dict, +]) +def test_create_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_create_product_rest_required_fields(request_type=product_service.CreateProductRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["product_id"] = "" + 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 + assert "productId" not in jsonified_request + + 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 + assert "productId" in jsonified_request + assert jsonified_request["productId"] == request_init["product_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["productId"] = 'product_id_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' + assert "productId" in jsonified_request + assert jsonified_request["productId"] == 'product_id_value' + + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_product.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 + + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product(request) + + expected_params = [ + ( + "productId", + "", + ), + ('$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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productId", )) & set(("parent", "product", "productId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_create_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_create_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.CreateProductRequest.pb(product_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 = gcr_product.Product.to_json(gcr_product.Product()) + + request = product_service.CreateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_product.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_service.CreateProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = ProductServiceClient( + 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 = gcr_product.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2/{parent=projects/*/locations/*/catalogs/*/branches/*}/products" % client.transport._host, args[1]) + + +def test_create_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +def test_create_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.GetProductRequest, + dict, +]) +def test_get_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_get_product_rest_required_fields(request_type=product_service.GetProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product.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 + + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(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.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_get_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_get_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.GetProductRequest.pb(product_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.Product.to_json(product.Product()) + + request = product_service.GetProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product.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_service.GetProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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 = ProductServiceClient( + 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.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # 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 + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_get_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.GetProductRequest(), + name='name_value', + ) + + +def test_get_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.ListProductsRequest, + dict, +]) +def test_list_products_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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_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 + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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_service.ListProductsRequest): + transport_class = transports.ProductServiceRestTransport + + 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(("filter", "page_size", "page_token", "read_mask", )) + 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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_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 + + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", "readMask", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_list_products") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_list_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.ListProductsRequest.pb(product_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_service.ListProductsResponse.to_json(product_service.ListProductsResponse()) + + request = product_service.ListProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_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_service.ListProductsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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.list_products(request) + + +def test_list_products_rest_flattened(): + client = ProductServiceClient( + 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_service.ListProductsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + + # 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 + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2/{parent=projects/*/locations/*/catalogs/*/branches/*}/products" % client.transport._host, args[1]) + + +def test_list_products_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_rest_pager(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_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/catalogs/sample3/branches/sample4'} + + pager = client.list_products(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product.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_service.UpdateProductRequest, + dict, +]) +def test_update_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_update_product_rest_required_fields(request_type=product_service.UpdateProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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(("allow_missing", "update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_product.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 + + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("allowMissing", "updateMask", )) & set(("product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_update_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_update_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.UpdateProductRequest.pb(product_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 = gcr_product.Product.to_json(gcr_product.Product()) + + request = product_service.UpdateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_product.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_service.UpdateProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = ProductServiceClient( + 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 = gcr_product.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + + # get truthy value for each flattened field + mock_args = dict( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2/{product.name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_update_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.DeleteProductRequest, + dict, +]) +def test_delete_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_service.DeleteProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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 = ProductServiceClient( + 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.ProductServiceRestTransport(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.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "pre_delete_product") as pre: + pre.assert_not_called() + pb_message = product_service.DeleteProductRequest.pb(product_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_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_service.DeleteProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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 = ProductServiceClient( + 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/catalogs/sample3/branches/sample4/products/sample5'} + + # 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/v2/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_delete_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + + +def test_delete_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportProductsRequest, + dict, +]) +def test_import_products_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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 = 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_products(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_products_rest_required_fields(request_type=import_config.ImportProductsRequest): + transport_class = transports.ProductServiceRestTransport + + 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_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()).import_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 = ProductServiceClient( + 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_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_products_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_products_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_import_products") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_import_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportProductsRequest.pb(import_config.ImportProductsRequest()) + 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 = import_config.ImportProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_products_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportProductsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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.import_products(request) + + +def test_import_products_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.SetInventoryRequest, + dict, +]) +def test_set_inventory_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + 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.set_inventory(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_set_inventory_rest_required_fields(request_type=product_service.SetInventoryRequest): + transport_class = transports.ProductServiceRestTransport + + 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()).set_inventory._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()).set_inventory._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductServiceClient( + 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.set_inventory(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_set_inventory_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.set_inventory._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("inventory", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_inventory_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_set_inventory") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_set_inventory") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.SetInventoryRequest.pb(product_service.SetInventoryRequest()) + 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_service.SetInventoryRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.set_inventory(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_set_inventory_rest_bad_request(transport: str = 'rest', request_type=product_service.SetInventoryRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + 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.set_inventory(request) + + +def test_set_inventory_rest_flattened(): + client = ProductServiceClient( + 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 = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + + # get truthy value for each flattened field + mock_args = dict( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.set_inventory(**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/v2/{inventory.name=projects/*/locations/*/catalogs/*/branches/*/products/**}:setInventory" % client.transport._host, args[1]) + + +def test_set_inventory_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_set_inventory_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddFulfillmentPlacesRequest, + dict, +]) +def test_add_fulfillment_places_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.add_fulfillment_places(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_add_fulfillment_places_rest_required_fields(request_type=product_service.AddFulfillmentPlacesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["type_"] = "" + request_init["place_ids"] = "" + 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_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["type"] = 'type__value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "type" in jsonified_request + assert jsonified_request["type"] == 'type__value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.add_fulfillment_places(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_fulfillment_places_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_fulfillment_places._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "type", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_fulfillment_places_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_add_fulfillment_places") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_add_fulfillment_places") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.AddFulfillmentPlacesRequest.pb(product_service.AddFulfillmentPlacesRequest()) + 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_service.AddFulfillmentPlacesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.add_fulfillment_places(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_fulfillment_places_rest_bad_request(transport: str = 'rest', request_type=product_service.AddFulfillmentPlacesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_fulfillment_places(request) + + +def test_add_fulfillment_places_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_fulfillment_places(**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/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addFulfillmentPlaces" % client.transport._host, args[1]) + + +def test_add_fulfillment_places_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +def test_add_fulfillment_places_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveFulfillmentPlacesRequest, + dict, +]) +def test_remove_fulfillment_places_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.remove_fulfillment_places(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_remove_fulfillment_places_rest_required_fields(request_type=product_service.RemoveFulfillmentPlacesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["type_"] = "" + request_init["place_ids"] = "" + 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_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["type"] = 'type__value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "type" in jsonified_request + assert jsonified_request["type"] == 'type__value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.remove_fulfillment_places(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_fulfillment_places_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_fulfillment_places._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "type", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_fulfillment_places_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_remove_fulfillment_places") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_remove_fulfillment_places") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.RemoveFulfillmentPlacesRequest.pb(product_service.RemoveFulfillmentPlacesRequest()) + 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_service.RemoveFulfillmentPlacesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.remove_fulfillment_places(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_fulfillment_places_rest_bad_request(transport: str = 'rest', request_type=product_service.RemoveFulfillmentPlacesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_fulfillment_places(request) + + +def test_remove_fulfillment_places_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_fulfillment_places(**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/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeFulfillmentPlaces" % client.transport._host, args[1]) + + +def test_remove_fulfillment_places_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + + +def test_remove_fulfillment_places_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddLocalInventoriesRequest, + dict, +]) +def test_add_local_inventories_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.add_local_inventories(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_add_local_inventories_rest_required_fields(request_type=product_service.AddLocalInventoriesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + 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_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductServiceClient( + 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.add_local_inventories(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_local_inventories_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_local_inventories._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "localInventories", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_local_inventories_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_add_local_inventories") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_add_local_inventories") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.AddLocalInventoriesRequest.pb(product_service.AddLocalInventoriesRequest()) + 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_service.AddLocalInventoriesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.add_local_inventories(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_local_inventories_rest_bad_request(transport: str = 'rest', request_type=product_service.AddLocalInventoriesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_local_inventories(request) + + +def test_add_local_inventories_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_local_inventories(**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/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addLocalInventories" % client.transport._host, args[1]) + + +def test_add_local_inventories_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + + +def test_add_local_inventories_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveLocalInventoriesRequest, + dict, +]) +def test_remove_local_inventories_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.remove_local_inventories(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_remove_local_inventories_rest_required_fields(request_type=product_service.RemoveLocalInventoriesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["place_ids"] = "" + 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_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.remove_local_inventories(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_local_inventories_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_local_inventories._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_local_inventories_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_remove_local_inventories") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_remove_local_inventories") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.RemoveLocalInventoriesRequest.pb(product_service.RemoveLocalInventoriesRequest()) + 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_service.RemoveLocalInventoriesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.remove_local_inventories(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_local_inventories_rest_bad_request(transport: str = 'rest', request_type=product_service.RemoveLocalInventoriesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_local_inventories(request) + + +def test_remove_local_inventories_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_local_inventories(**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/v2/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeLocalInventories" % client.transport._host, args[1]) + + +def test_remove_local_inventories_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + + +def test_remove_local_inventories_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductServiceClient( + 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 = ProductServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + transports.ProductServiceRestTransport, +]) +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 = ProductServiceClient.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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ProductServiceGrpcTransport, + ) + +def test_product_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_product_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.product_service.transports.ProductServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_product', + 'get_product', + 'list_products', + 'update_product', + 'delete_product', + 'import_products', + 'set_inventory', + 'add_fulfillment_places', + 'remove_fulfillment_places', + 'add_local_inventories', + 'remove_local_inventories', + 'get_operation', + 'list_operations', + ) + 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_service_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.retail_v2.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_product_service_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.retail_v2.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport() + adc.assert_called_once() + + +def test_product_service_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) + ProductServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + ], +) +def test_product_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + transports.ProductServiceRestTransport, + ], +) +def test_product_service_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.ProductServiceGrpcTransport, grpc_helpers), + (transports.ProductServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_product_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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_service_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.ProductServiceRestTransport ( + 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_service_rest_lro_client(): + client = ProductServiceClient( + 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_service_host_no_port(transport_name): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_service_host_with_port(transport_name): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_product_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ProductServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ProductServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_product._session + session2 = client2.transport.create_product._session + assert session1 != session2 + session1 = client1.transport.get_product._session + session2 = client2.transport.get_product._session + assert session1 != session2 + session1 = client1.transport.list_products._session + session2 = client2.transport.list_products._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.import_products._session + session2 = client2.transport.import_products._session + assert session1 != session2 + session1 = client1.transport.set_inventory._session + session2 = client2.transport.set_inventory._session + assert session1 != session2 + session1 = client1.transport.add_fulfillment_places._session + session2 = client2.transport.add_fulfillment_places._session + assert session1 != session2 + session1 = client1.transport.remove_fulfillment_places._session + session2 = client2.transport.remove_fulfillment_places._session + assert session1 != session2 + session1 = client1.transport.add_local_inventories._session + session2 = client2.transport.add_local_inventories._session + assert session1 != session2 + session1 = client1.transport.remove_local_inventories._session + session2 = client2.transport.remove_local_inventories._session + assert session1 != session2 +def test_product_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcTransport( + 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_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcAsyncIOTransport( + 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.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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_service_grpc_lro_client(): + client = ProductServiceClient( + 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_service_grpc_lro_async_client(): + client = ProductServiceAsyncClient( + 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_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = ProductServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = ProductServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_branch_path(path) + assert expected == actual + +def test_product_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + branch = "abalone" + product = "squid" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = ProductServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "clam", + "location": "whelk", + "catalog": "octopus", + "branch": "oyster", + "product": "nudibranch", + } + path = ProductServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ProductServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ProductServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = ProductServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ProductServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ProductServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ProductServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = ProductServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ProductServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ProductServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ProductServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.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.ProductServiceTransport, '_prep_wrapped_messages') as prep: + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ProductServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ProductServiceClient.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 = ProductServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ProductServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ProductServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ProductServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ProductServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ProductServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ProductServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ProductServiceClient( + 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 = ProductServiceClient( + 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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_search_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py new file mode 100644 index 00000000..d488a503 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_search_service.py @@ -0,0 +1,2263 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.search_service import SearchServiceAsyncClient +from google.cloud.retail_v2.services.search_service import SearchServiceClient +from google.cloud.retail_v2.services.search_service import pagers +from google.cloud.retail_v2.services.search_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +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 SearchServiceClient._get_default_mtls_endpoint(None) is None + assert SearchServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (SearchServiceClient, "grpc"), + (SearchServiceAsyncClient, "grpc_asyncio"), + (SearchServiceClient, "rest"), +]) +def test_search_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.SearchServiceGrpcTransport, "grpc"), + (transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.SearchServiceRestTransport, "rest"), +]) +def test_search_service_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", [ + (SearchServiceClient, "grpc"), + (SearchServiceAsyncClient, "grpc_asyncio"), + (SearchServiceClient, "rest"), +]) +def test_search_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_search_service_client_get_transport_class(): + transport = SearchServiceClient.get_transport_class() + available_transports = [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceRestTransport, + ] + assert transport in available_transports + + transport = SearchServiceClient.get_transport_class("grpc") + assert transport == transports.SearchServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_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(SearchServiceClient, '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(SearchServiceClient, '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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "true"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "false"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", "true"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_search_service_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", [ + SearchServiceClient, SearchServiceAsyncClient +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest"), +]) +def test_search_service_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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", grpc_helpers), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", None), +]) +def test_search_service_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_search_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = SearchServiceClient( + 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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", grpc_helpers), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_search_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + search_service.SearchRequest, + dict, +]) +def test_search(request_type, transport: str = 'grpc'): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + ) + response = client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +def test_search_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 = SearchServiceClient( + 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.search), + '__call__') as call: + client.search() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + +@pytest.mark.asyncio +async def test_search_async(transport: str = 'grpc_asyncio', request_type=search_service.SearchRequest): + client = SearchServiceAsyncClient( + 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + )) + response = await client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAsyncPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +@pytest.mark.asyncio +async def test_search_async_from_dict(): + await test_search_async(request_type=dict) + + +def test_search_field_headers(): + client = SearchServiceClient( + 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 = search_service.SearchRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = search_service.SearchResponse() + client.search(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_search_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = search_service.SearchRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse()) + await client.search(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', + 'placement=placement_value', + ) in kw['metadata'] + + +def test_search_pager(transport_name: str = "grpc"): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('placement', ''), + )), + ) + pager = client.search(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in results) +def test_search_pages(transport_name: str = "grpc"): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + pages = list(client.search(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_search_async_pager(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + async_pager = await client.search(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, search_service.SearchResponse.SearchResult) + for i in responses) + + +@pytest.mark.asyncio +async def test_search_async_pages(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + 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.search(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", [ + search_service.SearchRequest, + dict, +]) +def test_search_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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 = search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = search_service.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.search(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +def test_search_rest_required_fields(request_type=search_service.SearchRequest): + transport_class = transports.SearchServiceRestTransport + + request_init = {} + request_init["placement"] = "" + request_init["visitor_id"] = "" + 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()).search._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["placement"] = 'placement_value' + jsonified_request["visitorId"] = 'visitor_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).search._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "placement" in jsonified_request + assert jsonified_request["placement"] == 'placement_value' + assert "visitorId" in jsonified_request + assert jsonified_request["visitorId"] == 'visitor_id_value' + + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = search_service.SearchResponse() + # 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 + + pb_return_value = search_service.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.search(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_search_rest_unset_required_fields(): + transport = transports.SearchServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.search._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("placement", "visitorId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_rest_interceptors(null_interceptor): + transport = transports.SearchServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.SearchServiceRestInterceptor(), + ) + client = SearchServiceClient(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.SearchServiceRestInterceptor, "post_search") as post, \ + mock.patch.object(transports.SearchServiceRestInterceptor, "pre_search") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) + 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 = search_service.SearchResponse.to_json(search_service.SearchResponse()) + + request = search_service.SearchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = search_service.SearchResponse() + + client.search(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_search_rest_bad_request(transport: str = 'rest', request_type=search_service.SearchRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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.search(request) + + +def test_search_rest_pager(transport: str = 'rest'): + client = SearchServiceClient( + 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 = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(search_service.SearchResponse.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 = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/sample4'} + + pager = client.search(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in results) + + pages = list(client.search(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SearchServiceClient( + 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 = SearchServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SearchServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SearchServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + transports.SearchServiceRestTransport, +]) +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 = SearchServiceClient.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 = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.SearchServiceGrpcTransport, + ) + +def test_search_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_search_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.search_service.transports.SearchServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'search', + 'get_operation', + 'list_operations', + ) + 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_search_service_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.retail_v2.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_search_service_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.retail_v2.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport() + adc.assert_called_once() + + +def test_search_service_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) + SearchServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + ], +) +def test_search_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + transports.SearchServiceRestTransport, + ], +) +def test_search_service_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.SearchServiceGrpcTransport, grpc_helpers), + (transports.SearchServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_search_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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_search_service_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.SearchServiceRestTransport ( + 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_search_service_host_no_port(transport_name): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_search_service_host_with_port(transport_name): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_search_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = SearchServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = SearchServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.search._session + session2 = client2.transport.search._session + assert session1 != session2 +def test_search_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcTransport( + 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_search_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcAsyncIOTransport( + 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.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = SearchServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = SearchServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_branch_path(path) + assert expected == actual + +def test_experiment_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + experiment = "abalone" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format(project=project, location=location, catalog=catalog, experiment=experiment, ) + actual = SearchServiceClient.experiment_path(project, location, catalog, experiment) + assert expected == actual + + +def test_parse_experiment_path(): + expected = { + "project": "squid", + "location": "clam", + "catalog": "whelk", + "experiment": "octopus", + } + path = SearchServiceClient.experiment_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_experiment_path(path) + assert expected == actual + +def test_product_path(): + project = "oyster" + location = "nudibranch" + catalog = "cuttlefish" + branch = "mussel" + product = "winkle" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = SearchServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "catalog": "abalone", + "branch": "squid", + "product": "clam", + } + path = SearchServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_product_path(path) + assert expected == actual + +def test_serving_config_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + serving_config = "nudibranch" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + actual = SearchServiceClient.serving_config_path(project, location, catalog, serving_config) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + "catalog": "winkle", + "serving_config": "nautilus", + } + path = SearchServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_serving_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = SearchServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = SearchServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = SearchServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = SearchServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = SearchServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = SearchServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = SearchServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = SearchServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = SearchServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = SearchServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.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.SearchServiceTransport, '_prep_wrapped_messages') as prep: + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.SearchServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = SearchServiceClient.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 = SearchServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = SearchServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = SearchServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = SearchServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = SearchServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = SearchServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = SearchServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = SearchServiceClient( + 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 = SearchServiceClient( + 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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_serving_config_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_serving_config_service.py new file mode 100644 index 00000000..16eb6800 --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_serving_config_service.py @@ -0,0 +1,5655 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2.services.serving_config_service import ServingConfigServiceAsyncClient +from google.cloud.retail_v2.services.serving_config_service import ServingConfigServiceClient +from google.cloud.retail_v2.services.serving_config_service import pagers +from google.cloud.retail_v2.services.serving_config_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import search_service +from google.cloud.retail_v2.types import serving_config +from google.cloud.retail_v2.types import serving_config as gcr_serving_config +from google.cloud.retail_v2.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_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 ServingConfigServiceClient._get_default_mtls_endpoint(None) is None + assert ServingConfigServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ServingConfigServiceClient, "grpc"), + (ServingConfigServiceAsyncClient, "grpc_asyncio"), + (ServingConfigServiceClient, "rest"), +]) +def test_serving_config_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ServingConfigServiceGrpcTransport, "grpc"), + (transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ServingConfigServiceRestTransport, "rest"), +]) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, "grpc"), + (ServingConfigServiceAsyncClient, "grpc_asyncio"), + (ServingConfigServiceClient, "rest"), +]) +def test_serving_config_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_serving_config_service_client_get_transport_class(): + transport = ServingConfigServiceClient.get_transport_class() + available_transports = [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceRestTransport, + ] + assert transport in available_transports + + transport = ServingConfigServiceClient.get_transport_class("grpc") + assert transport == transports.ServingConfigServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest"), +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +def test_serving_config_service_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(ServingConfigServiceClient, '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(ServingConfigServiceClient, '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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", "true"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", "false"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", "true"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_serving_config_service_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", [ + ServingConfigServiceClient, ServingConfigServiceAsyncClient +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest"), +]) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", grpc_helpers), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", None), +]) +def test_serving_config_service_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_serving_config_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.serving_config_service.transports.ServingConfigServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ServingConfigServiceClient( + 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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", grpc_helpers), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_serving_config_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.CreateServingConfigRequest, + dict, +]) +def test_create_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.create_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_create_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.create_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + +@pytest.mark.asyncio +async def test_create_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.CreateServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.create_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_create_serving_config_async_from_dict(): + await test_create_serving_config_async(request_type=dict) + + +def test_create_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.CreateServingConfigRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.create_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.CreateServingConfigRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.create_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_serving_config( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_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].serving_config + mock_val = gcr_serving_config.ServingConfig(name='name_value') + assert arg == mock_val + arg = args[0].serving_config_id + mock_val = 'serving_config_id_value' + assert arg == mock_val + + +def test_create_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + +@pytest.mark.asyncio +async def test_create_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_serving_config( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_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].serving_config + mock_val = gcr_serving_config.ServingConfig(name='name_value') + assert arg == mock_val + arg = args[0].serving_config_id + mock_val = 'serving_config_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.DeleteServingConfigRequest, + dict, +]) +def test_delete_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.delete_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + +@pytest.mark.asyncio +async def test_delete_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.DeleteServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_serving_config_async_from_dict(): + await test_delete_serving_config_async(request_type=dict) + + +def test_delete_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.DeleteServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__call__') as call: + call.return_value = None + client.delete_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.DeleteServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__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_serving_config( + 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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__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_serving_config( + 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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.UpdateServingConfigRequest, + dict, +]) +def test_update_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.update_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_update_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.update_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + +@pytest.mark.asyncio +async def test_update_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.UpdateServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.update_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_update_serving_config_async_from_dict(): + await test_update_serving_config_async(request_type=dict) + + +def test_update_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.UpdateServingConfigRequest() + + request.serving_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.update_serving_config(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', + 'serving_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.UpdateServingConfigRequest() + + request.serving_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.update_serving_config(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', + 'serving_config.name=name_value', + ) in kw['metadata'] + + +def test_update_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_serving_config( + serving_config=gcr_serving_config.ServingConfig(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].serving_config + mock_val = gcr_serving_config.ServingConfig(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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_serving_config( + serving_config=gcr_serving_config.ServingConfig(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].serving_config + mock_val = gcr_serving_config.ServingConfig(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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.GetServingConfigRequest, + dict, +]) +def test_get_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.get_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_get_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.get_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + +@pytest.mark.asyncio +async def test_get_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.GetServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.get_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_get_serving_config_async_from_dict(): + await test_get_serving_config_async(request_type=dict) + + +def test_get_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.GetServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + call.return_value = serving_config.ServingConfig() + client.get_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.GetServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig()) + await client.get_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_serving_config( + 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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_serving_config( + 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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.ListServingConfigsRequest, + dict, +]) +def test_list_serving_configs(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_serving_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_serving_configs_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 = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + client.list_serving_configs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + +@pytest.mark.asyncio +async def test_list_serving_configs_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.ListServingConfigsRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_serving_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_serving_configs_async_from_dict(): + await test_list_serving_configs_async(request_type=dict) + + +def test_list_serving_configs_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.ListServingConfigsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + call.return_value = serving_config_service.ListServingConfigsResponse() + client.list_serving_configs(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_serving_configs_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.ListServingConfigsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse()) + await client.list_serving_configs(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_serving_configs_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_serving_configs( + 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_serving_configs_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_serving_configs_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_serving_configs( + 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_serving_configs_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + + +def test_list_serving_configs_pager(transport_name: str = "grpc"): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_serving_configs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, serving_config.ServingConfig) + for i in results) +def test_list_serving_configs_pages(transport_name: str = "grpc"): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + pages = list(client.list_serving_configs(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_serving_configs_async_pager(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_serving_configs(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, serving_config.ServingConfig) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_serving_configs_async_pages(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + 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_serving_configs(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", [ + serving_config_service.AddControlRequest, + dict, +]) +def test_add_control(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.add_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_add_control_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 = ServingConfigServiceClient( + 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_control), + '__call__') as call: + client.add_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + +@pytest.mark.asyncio +async def test_add_control_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.AddControlRequest): + client = ServingConfigServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.add_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_add_control_async_from_dict(): + await test_add_control_async(request_type=dict) + + +def test_add_control_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.AddControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.add_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_control_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.AddControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.add_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +def test_add_control_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.add_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + + +def test_add_control_flattened_error(): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + +@pytest.mark.asyncio +async def test_add_control_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.add_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_control_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.RemoveControlRequest, + dict, +]) +def test_remove_control(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.remove_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_remove_control_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 = ServingConfigServiceClient( + 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_control), + '__call__') as call: + client.remove_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + +@pytest.mark.asyncio +async def test_remove_control_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.RemoveControlRequest): + client = ServingConfigServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.remove_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_remove_control_async_from_dict(): + await test_remove_control_async(request_type=dict) + + +def test_remove_control_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.RemoveControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.remove_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_control_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.RemoveControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.remove_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +def test_remove_control_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.remove_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + + +def test_remove_control_flattened_error(): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + +@pytest.mark.asyncio +async def test_remove_control_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.remove_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_control_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.CreateServingConfigRequest, + dict, +]) +def test_create_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["serving_config"] = {'name': 'name_value', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_create_serving_config_rest_required_fields(request_type=serving_config_service.CreateServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["serving_config_id"] = "" + 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 + assert "servingConfigId" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_serving_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "servingConfigId" in jsonified_request + assert jsonified_request["servingConfigId"] == request_init["serving_config_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["servingConfigId"] = 'serving_config_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_serving_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("serving_config_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' + assert "servingConfigId" in jsonified_request + assert jsonified_request["servingConfigId"] == 'serving_config_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_serving_config(request) + + expected_params = [ + ( + "servingConfigId", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("servingConfigId", )) & set(("parent", "servingConfig", "servingConfigId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_create_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_create_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.CreateServingConfigRequest.pb(serving_config_service.CreateServingConfigRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.CreateServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.create_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.CreateServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["serving_config"] = {'name': 'name_value', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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_serving_config(request) + + +def test_create_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_serving_config(**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/v2/{parent=projects/*/locations/*/catalogs/*}/servingConfigs" % client.transport._host, args[1]) + + +def test_create_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + + +def test_create_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.DeleteServingConfigRequest, + dict, +]) +def test_delete_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_serving_config_rest_required_fields(request_type=serving_config_service.DeleteServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + 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_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "pre_delete_serving_config") as pre: + pre.assert_not_called() + pb_message = serving_config_service.DeleteServingConfigRequest.pb(serving_config_service.DeleteServingConfigRequest()) + 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 = serving_config_service.DeleteServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.DeleteServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + +def test_delete_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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/catalogs/sample3/servingConfigs/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_serving_config(**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/v2/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_delete_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + + +def test_delete_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.UpdateServingConfigRequest, + dict, +]) +def test_update_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + request_init["serving_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_update_serving_config_rest_required_fields(request_type=serving_config_service.UpdateServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("servingConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_update_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_update_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.UpdateServingConfigRequest.pb(serving_config_service.UpdateServingConfigRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.UpdateServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.update_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.UpdateServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + request_init["serving_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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_serving_config(request) + + +def test_update_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + serving_config=gcr_serving_config.ServingConfig(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 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_serving_config(**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/v2/{serving_config.name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_update_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.GetServingConfigRequest, + dict, +]) +def test_get_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_get_serving_config_rest_required_fields(request_type=serving_config_service.GetServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = serving_config.ServingConfig() + # 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 + + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_get_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_get_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.GetServingConfigRequest.pb(serving_config_service.GetServingConfigRequest()) + 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 = serving_config.ServingConfig.to_json(serving_config.ServingConfig()) + + request = serving_config_service.GetServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = serving_config.ServingConfig() + + client.get_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.GetServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + +def test_get_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_serving_config(**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/v2/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_get_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + + +def test_get_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.ListServingConfigsRequest, + dict, +]) +def test_list_serving_configs_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_serving_configs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_serving_configs_rest_required_fields(request_type=serving_config_service.ListServingConfigsRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_configs._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_serving_configs._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = serving_config_service.ListServingConfigsResponse() + # 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 + + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_serving_configs(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_serving_configs_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_serving_configs._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_serving_configs_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_list_serving_configs") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_list_serving_configs") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.ListServingConfigsRequest.pb(serving_config_service.ListServingConfigsRequest()) + 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 = serving_config_service.ListServingConfigsResponse.to_json(serving_config_service.ListServingConfigsResponse()) + + request = serving_config_service.ListServingConfigsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = serving_config_service.ListServingConfigsResponse() + + client.list_serving_configs(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_serving_configs_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.ListServingConfigsRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_serving_configs(request) + + +def test_list_serving_configs_rest_flattened(): + client = ServingConfigServiceClient( + 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 = serving_config_service.ListServingConfigsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_serving_configs(**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/v2/{parent=projects/*/locations/*/catalogs/*}/servingConfigs" % client.transport._host, args[1]) + + +def test_list_serving_configs_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + + +def test_list_serving_configs_rest_pager(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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 = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(serving_config_service.ListServingConfigsResponse.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/catalogs/sample3'} + + pager = client.list_serving_configs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, serving_config.ServingConfig) + for i in results) + + pages = list(client.list_serving_configs(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", [ + serving_config_service.AddControlRequest, + dict, +]) +def test_add_control_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_add_control_rest_required_fields(request_type=serving_config_service.AddControlRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["serving_config"] = "" + request_init["control_id"] = "" + 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_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["servingConfig"] = 'serving_config_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "servingConfig" in jsonified_request + assert jsonified_request["servingConfig"] == 'serving_config_value' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_control_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("servingConfig", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_control_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_add_control") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_add_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.AddControlRequest.pb(serving_config_service.AddControlRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.AddControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.add_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_control_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.AddControlRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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.add_control(request) + + +def test_add_control_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + serving_config='serving_config_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_control(**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/v2/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:addControl" % client.transport._host, args[1]) + + +def test_add_control_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + + +def test_add_control_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.RemoveControlRequest, + dict, +]) +def test_remove_control_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_remove_control_rest_required_fields(request_type=serving_config_service.RemoveControlRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["serving_config"] = "" + request_init["control_id"] = "" + 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_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["servingConfig"] = 'serving_config_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "servingConfig" in jsonified_request + assert jsonified_request["servingConfig"] == 'serving_config_value' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_control_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("servingConfig", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_control_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_remove_control") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_remove_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.RemoveControlRequest.pb(serving_config_service.RemoveControlRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.RemoveControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.remove_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_control_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.RemoveControlRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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.remove_control(request) + + +def test_remove_control_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + serving_config='serving_config_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_control(**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/v2/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:removeControl" % client.transport._host, args[1]) + + +def test_remove_control_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + + +def test_remove_control_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + 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 = ServingConfigServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ServingConfigServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ServingConfigServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + transports.ServingConfigServiceRestTransport, +]) +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 = ServingConfigServiceClient.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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ServingConfigServiceGrpcTransport, + ) + +def test_serving_config_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ServingConfigServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_serving_config_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.serving_config_service.transports.ServingConfigServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ServingConfigServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_serving_config', + 'delete_serving_config', + 'update_serving_config', + 'get_serving_config', + 'list_serving_configs', + 'add_control', + 'remove_control', + 'get_operation', + 'list_operations', + ) + 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_serving_config_service_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.retail_v2.services.serving_config_service.transports.ServingConfigServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServingConfigServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_serving_config_service_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.retail_v2.services.serving_config_service.transports.ServingConfigServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServingConfigServiceTransport() + adc.assert_called_once() + + +def test_serving_config_service_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) + ServingConfigServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + ], +) +def test_serving_config_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + transports.ServingConfigServiceRestTransport, + ], +) +def test_serving_config_service_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.ServingConfigServiceGrpcTransport, grpc_helpers), + (transports.ServingConfigServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_serving_config_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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_serving_config_service_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.ServingConfigServiceRestTransport ( + 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_serving_config_service_host_no_port(transport_name): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_serving_config_service_host_with_port(transport_name): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_serving_config_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ServingConfigServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ServingConfigServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_serving_config._session + session2 = client2.transport.create_serving_config._session + assert session1 != session2 + session1 = client1.transport.delete_serving_config._session + session2 = client2.transport.delete_serving_config._session + assert session1 != session2 + session1 = client1.transport.update_serving_config._session + session2 = client2.transport.update_serving_config._session + assert session1 != session2 + session1 = client1.transport.get_serving_config._session + session2 = client2.transport.get_serving_config._session + assert session1 != session2 + session1 = client1.transport.list_serving_configs._session + session2 = client2.transport.list_serving_configs._session + assert session1 != session2 + session1 = client1.transport.add_control._session + session2 = client2.transport.add_control._session + assert session1 != session2 + session1 = client1.transport.remove_control._session + session2 = client2.transport.remove_control._session + assert session1 != session2 +def test_serving_config_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ServingConfigServiceGrpcTransport( + 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_serving_config_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ServingConfigServiceGrpcAsyncIOTransport( + 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.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ServingConfigServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ServingConfigServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_serving_config_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + serving_config = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + actual = ServingConfigServiceClient.serving_config_path(project, location, catalog, serving_config) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "serving_config": "clam", + } + path = ServingConfigServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_serving_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ServingConfigServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ServingConfigServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ServingConfigServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ServingConfigServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ServingConfigServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ServingConfigServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ServingConfigServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ServingConfigServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ServingConfigServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ServingConfigServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.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.ServingConfigServiceTransport, '_prep_wrapped_messages') as prep: + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ServingConfigServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ServingConfigServiceClient.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 = ServingConfigServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ServingConfigServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ServingConfigServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ServingConfigServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ServingConfigServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ServingConfigServiceClient( + 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 = ServingConfigServiceClient( + 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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport), +]) +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/v2/tests/unit/gapic/retail_v2/test_user_event_service.py b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py new file mode 100644 index 00000000..9b7d599f --- /dev/null +++ b/owl-bot-staging/v2/tests/unit/gapic/retail_v2/test_user_event_service.py @@ -0,0 +1,3431 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 import httpbody_pb2 # type: ignore +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.location import locations_pb2 +from google.cloud.retail_v2.services.user_event_service import UserEventServiceAsyncClient +from google.cloud.retail_v2.services.user_event_service import UserEventServiceClient +from google.cloud.retail_v2.services.user_event_service import transports +from google.cloud.retail_v2.types import common +from google.cloud.retail_v2.types import import_config +from google.cloud.retail_v2.types import product +from google.cloud.retail_v2.types import promotion +from google.cloud.retail_v2.types import purge_config +from google.cloud.retail_v2.types import user_event +from google.cloud.retail_v2.types import user_event_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 duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.type import date_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 UserEventServiceClient._get_default_mtls_endpoint(None) is None + assert UserEventServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (UserEventServiceClient, "grpc"), + (UserEventServiceAsyncClient, "grpc_asyncio"), + (UserEventServiceClient, "rest"), +]) +def test_user_event_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.UserEventServiceGrpcTransport, "grpc"), + (transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.UserEventServiceRestTransport, "rest"), +]) +def test_user_event_service_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", [ + (UserEventServiceClient, "grpc"), + (UserEventServiceAsyncClient, "grpc_asyncio"), + (UserEventServiceClient, "rest"), +]) +def test_user_event_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_user_event_service_client_get_transport_class(): + transport = UserEventServiceClient.get_transport_class() + available_transports = [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceRestTransport, + ] + assert transport in available_transports + + transport = UserEventServiceClient.get_transport_class("grpc") + assert transport == transports.UserEventServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_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(UserEventServiceClient, '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(UserEventServiceClient, '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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "true"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "false"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", "true"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_user_event_service_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", [ + UserEventServiceClient, UserEventServiceAsyncClient +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest"), +]) +def test_user_event_service_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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", grpc_helpers), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", None), +]) +def test_user_event_service_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_user_event_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = UserEventServiceClient( + 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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", grpc_helpers), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_user_event_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.WriteUserEventRequest, + dict, +]) +def test_write_user_event(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + ) + response = client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +def test_write_user_event_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 = UserEventServiceClient( + 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.write_user_event), + '__call__') as call: + client.write_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + +@pytest.mark.asyncio +async def test_write_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.WriteUserEventRequest): + client = UserEventServiceAsyncClient( + 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + )) + response = await client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +@pytest.mark.asyncio +async def test_write_user_event_async_from_dict(): + await test_write_user_event_async(request_type=dict) + + +def test_write_user_event_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.WriteUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = user_event.UserEvent() + client.write_user_event(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_write_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.WriteUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent()) + await client.write_user_event(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.CollectUserEventRequest, + dict, +]) +def test_collect_user_event(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.collect_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + ) + response = client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +def test_collect_user_event_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 = UserEventServiceClient( + 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.collect_user_event), + '__call__') as call: + client.collect_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + +@pytest.mark.asyncio +async def test_collect_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.CollectUserEventRequest): + client = UserEventServiceAsyncClient( + 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.collect_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + )) + response = await client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +@pytest.mark.asyncio +async def test_collect_user_event_async_from_dict(): + await test_collect_user_event_async(request_type=dict) + + +def test_collect_user_event_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.CollectUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = httpbody_pb2.HttpBody() + client.collect_user_event(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_collect_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.CollectUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody()) + await client.collect_user_event(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'] + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeUserEventsRequest, + dict, +]) +def test_purge_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.purge_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_purge_user_events_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 = UserEventServiceClient( + 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_user_events), + '__call__') as call: + client.purge_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + +@pytest.mark.asyncio +async def test_purge_user_events_async(transport: str = 'grpc_asyncio', request_type=purge_config.PurgeUserEventsRequest): + client = UserEventServiceAsyncClient( + 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_user_events), + '__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_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_purge_user_events_async_from_dict(): + await test_purge_user_events_async(request_type=dict) + + +def test_purge_user_events_field_headers(): + client = UserEventServiceClient( + 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 = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.purge_user_events(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_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.purge_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportUserEventsRequest, + dict, +]) +def test_import_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_user_events_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 = UserEventServiceClient( + 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_user_events), + '__call__') as call: + client.import_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + +@pytest.mark.asyncio +async def test_import_user_events_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportUserEventsRequest): + client = UserEventServiceAsyncClient( + 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_user_events), + '__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_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_user_events_async_from_dict(): + await test_import_user_events_async(request_type=dict) + + +def test_import_user_events_field_headers(): + client = UserEventServiceClient( + 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 = import_config.ImportUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_user_events(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_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = import_config.ImportUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.RejoinUserEventsRequest, + dict, +]) +def test_rejoin_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.rejoin_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_rejoin_user_events_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 = UserEventServiceClient( + 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.rejoin_user_events), + '__call__') as call: + client.rejoin_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + +@pytest.mark.asyncio +async def test_rejoin_user_events_async(transport: str = 'grpc_asyncio', request_type=user_event_service.RejoinUserEventsRequest): + client = UserEventServiceAsyncClient( + 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.rejoin_user_events), + '__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.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_rejoin_user_events_async_from_dict(): + await test_rejoin_user_events_async(request_type=dict) + + +def test_rejoin_user_events_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.rejoin_user_events(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_rejoin_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.rejoin_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.WriteUserEventRequest, + dict, +]) +def test_write_user_event_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["user_event"] = {'event_type': 'event_type_value', 'visitor_id': 'visitor_id_value', 'session_id': 'session_id_value', 'event_time': {'seconds': 751, 'nanos': 543}, 'experiment_ids': ['experiment_ids_value1', 'experiment_ids_value2'], 'attribution_token': 'attribution_token_value', 'product_details': [{'product': {'expire_time': {}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]}, 'quantity': {}}], 'completion_detail': {'completion_attribution_token': 'completion_attribution_token_value', 'selected_suggestion': 'selected_suggestion_value', 'selected_position': 1821}, 'attributes': {}, 'cart_id': 'cart_id_value', 'purchase_transaction': {'id': 'id_value', 'revenue': 0.762, 'tax': 0.333, 'cost': 0.441, 'currency_code': 'currency_code_value'}, 'search_query': 'search_query_value', 'filter': 'filter_value', 'order_by': 'order_by_value', 'offset': 647, 'page_categories': ['page_categories_value1', 'page_categories_value2'], 'user_info': {'user_id': 'user_id_value', 'ip_address': 'ip_address_value', 'user_agent': 'user_agent_value', 'direct_user_request': True}, 'uri': 'uri_value', 'referrer_uri': 'referrer_uri_value', 'page_view_id': 'page_view_id_value', 'entity': 'entity_value'} + 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 = user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = user_event.UserEvent.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.write_user_event(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +def test_write_user_event_rest_required_fields(request_type=user_event_service.WriteUserEventRequest): + transport_class = transports.UserEventServiceRestTransport + + 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()).write_user_event._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()).write_user_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("write_async", )) + 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 = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = user_event.UserEvent() + # 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 + + pb_return_value = user_event.UserEvent.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.write_user_event(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_write_user_event_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.write_user_event._get_unset_required_fields({}) + assert set(unset_fields) == (set(("writeAsync", )) & set(("parent", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_write_user_event_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_write_user_event") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_write_user_event") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.WriteUserEventRequest.pb(user_event_service.WriteUserEventRequest()) + 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 = user_event.UserEvent.to_json(user_event.UserEvent()) + + request = user_event_service.WriteUserEventRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = user_event.UserEvent() + + client.write_user_event(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_write_user_event_rest_bad_request(transport: str = 'rest', request_type=user_event_service.WriteUserEventRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["user_event"] = {'event_type': 'event_type_value', 'visitor_id': 'visitor_id_value', 'session_id': 'session_id_value', 'event_time': {'seconds': 751, 'nanos': 543}, 'experiment_ids': ['experiment_ids_value1', 'experiment_ids_value2'], 'attribution_token': 'attribution_token_value', 'product_details': [{'product': {'expire_time': {}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]}, 'quantity': {}}], 'completion_detail': {'completion_attribution_token': 'completion_attribution_token_value', 'selected_suggestion': 'selected_suggestion_value', 'selected_position': 1821}, 'attributes': {}, 'cart_id': 'cart_id_value', 'purchase_transaction': {'id': 'id_value', 'revenue': 0.762, 'tax': 0.333, 'cost': 0.441, 'currency_code': 'currency_code_value'}, 'search_query': 'search_query_value', 'filter': 'filter_value', 'order_by': 'order_by_value', 'offset': 647, 'page_categories': ['page_categories_value1', 'page_categories_value2'], 'user_info': {'user_id': 'user_id_value', 'ip_address': 'ip_address_value', 'user_agent': 'user_agent_value', 'direct_user_request': True}, 'uri': 'uri_value', 'referrer_uri': 'referrer_uri_value', 'page_view_id': 'page_view_id_value', 'entity': 'entity_value'} + 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.write_user_event(request) + + +def test_write_user_event_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.CollectUserEventRequest, + dict, +]) +def test_collect_user_event_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.collect_user_event(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +def test_collect_user_event_rest_required_fields(request_type=user_event_service.CollectUserEventRequest): + transport_class = transports.UserEventServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["user_event"] = "" + 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 + assert "userEvent" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).collect_user_event._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "userEvent" in jsonified_request + assert jsonified_request["userEvent"] == request_init["user_event"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["userEvent"] = 'user_event_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).collect_user_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("ets", "prebuilt_rule", "raw_json", "uri", "user_event", )) + 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' + assert "userEvent" in jsonified_request + assert jsonified_request["userEvent"] == 'user_event_value' + + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = httpbody_pb2.HttpBody() + # 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 + + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.collect_user_event(request) + + expected_params = [ + ( + "userEvent", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_collect_user_event_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.collect_user_event._get_unset_required_fields({}) + assert set(unset_fields) == (set(("ets", "prebuiltRule", "rawJson", "uri", "userEvent", )) & set(("parent", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_collect_user_event_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_collect_user_event") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_collect_user_event") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.CollectUserEventRequest.pb(user_event_service.CollectUserEventRequest()) + 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(httpbody_pb2.HttpBody()) + + request = user_event_service.CollectUserEventRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = httpbody_pb2.HttpBody() + + client.collect_user_event(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_collect_user_event_rest_bad_request(transport: str = 'rest', request_type=user_event_service.CollectUserEventRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.collect_user_event(request) + + +def test_collect_user_event_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeUserEventsRequest, + dict, +]) +def test_purge_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_purge_user_events_rest_required_fields(request_type=purge_config.PurgeUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["filter"] = "" + 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_user_events._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' + jsonified_request["filter"] = 'filter_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).purge_user_events._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' + assert "filter" in jsonified_request + assert jsonified_request["filter"] == 'filter_value' + + client = UserEventServiceClient( + 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_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_purge_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.purge_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "filter", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_purge_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_purge_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_purge_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = purge_config.PurgeUserEventsRequest.pb(purge_config.PurgeUserEventsRequest()) + 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 = purge_config.PurgeUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.purge_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_purge_user_events_rest_bad_request(transport: str = 'rest', request_type=purge_config.PurgeUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.purge_user_events(request) + + +def test_purge_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportUserEventsRequest, + dict, +]) +def test_import_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_user_events_rest_required_fields(request_type=import_config.ImportUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + 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_user_events._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_user_events._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 = UserEventServiceClient( + 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_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_import_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_import_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportUserEventsRequest.pb(import_config.ImportUserEventsRequest()) + 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 = import_config.ImportUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_user_events_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.import_user_events(request) + + +def test_import_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.RejoinUserEventsRequest, + dict, +]) +def test_rejoin_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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.rejoin_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_rejoin_user_events_rest_required_fields(request_type=user_event_service.RejoinUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + 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()).rejoin_user_events._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()).rejoin_user_events._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 = UserEventServiceClient( + 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.rejoin_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_rejoin_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.rejoin_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_rejoin_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_rejoin_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_rejoin_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.RejoinUserEventsRequest.pb(user_event_service.RejoinUserEventsRequest()) + 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 = user_event_service.RejoinUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.rejoin_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_rejoin_user_events_rest_bad_request(transport: str = 'rest', request_type=user_event_service.RejoinUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.rejoin_user_events(request) + + +def test_rejoin_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserEventServiceClient( + 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 = UserEventServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = UserEventServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.UserEventServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + transports.UserEventServiceRestTransport, +]) +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 = UserEventServiceClient.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 = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.UserEventServiceGrpcTransport, + ) + +def test_user_event_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_user_event_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2.services.user_event_service.transports.UserEventServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'write_user_event', + 'collect_user_event', + 'purge_user_events', + 'import_user_events', + 'rejoin_user_events', + 'get_operation', + 'list_operations', + ) + 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_user_event_service_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.retail_v2.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_user_event_service_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.retail_v2.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport() + adc.assert_called_once() + + +def test_user_event_service_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) + UserEventServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + ], +) +def test_user_event_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + transports.UserEventServiceRestTransport, + ], +) +def test_user_event_service_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.UserEventServiceGrpcTransport, grpc_helpers), + (transports.UserEventServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_user_event_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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_user_event_service_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.UserEventServiceRestTransport ( + 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_user_event_service_rest_lro_client(): + client = UserEventServiceClient( + 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_user_event_service_host_no_port(transport_name): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_user_event_service_host_with_port(transport_name): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_user_event_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = UserEventServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = UserEventServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.write_user_event._session + session2 = client2.transport.write_user_event._session + assert session1 != session2 + session1 = client1.transport.collect_user_event._session + session2 = client2.transport.collect_user_event._session + assert session1 != session2 + session1 = client1.transport.purge_user_events._session + session2 = client2.transport.purge_user_events._session + assert session1 != session2 + session1 = client1.transport.import_user_events._session + session2 = client2.transport.import_user_events._session + assert session1 != session2 + session1 = client1.transport.rejoin_user_events._session + session2 = client2.transport.rejoin_user_events._session + assert session1 != session2 +def test_user_event_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcTransport( + 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_user_event_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcAsyncIOTransport( + 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.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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_user_event_service_grpc_lro_client(): + client = UserEventServiceClient( + 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_user_event_service_grpc_lro_async_client(): + client = UserEventServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = UserEventServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = UserEventServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_product_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + branch = "nautilus" + product = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = UserEventServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + "branch": "whelk", + "product": "octopus", + } + path = UserEventServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = UserEventServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = UserEventServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format(folder=folder, ) + actual = UserEventServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = UserEventServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format(organization=organization, ) + actual = UserEventServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = UserEventServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format(project=project, ) + actual = UserEventServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = UserEventServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "squid" + location = "clam" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = UserEventServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = UserEventServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.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.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = UserEventServiceClient.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 = UserEventServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/operations/sample3'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/operations/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 = operations_pb2.Operation() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': '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.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = UserEventServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = UserEventServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = UserEventServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = UserEventServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = UserEventServiceClient( + 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 = UserEventServiceClient( + 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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport), +]) +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/v2alpha/.coveragerc b/owl-bot-staging/v2alpha/.coveragerc new file mode 100644 index 00000000..3d15c56d --- /dev/null +++ b/owl-bot-staging/v2alpha/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/retail/__init__.py + google/cloud/retail/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/v2alpha/.flake8 b/owl-bot-staging/v2alpha/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v2alpha/.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/v2alpha/MANIFEST.in b/owl-bot-staging/v2alpha/MANIFEST.in new file mode 100644 index 00000000..3ee710cc --- /dev/null +++ b/owl-bot-staging/v2alpha/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/retail *.py +recursive-include google/cloud/retail_v2alpha *.py diff --git a/owl-bot-staging/v2alpha/README.rst b/owl-bot-staging/v2alpha/README.rst new file mode 100644 index 00000000..cb039760 --- /dev/null +++ b/owl-bot-staging/v2alpha/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Retail 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 Retail 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/v2alpha/docs/_static/custom.css b/owl-bot-staging/v2alpha/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v2alpha/docs/conf.py b/owl-bot-staging/v2alpha/docs/conf.py new file mode 100644 index 00000000..995e6a64 --- /dev/null +++ b/owl-bot-staging/v2alpha/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-retail 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-retail" +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-retail-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-retail.tex", + u"google-cloud-retail 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-retail", + u"Google Cloud Retail 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-retail", + u"google-cloud-retail Documentation", + author, + "google-cloud-retail", + "GAPIC library for Google Cloud Retail 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/v2alpha/docs/index.rst b/owl-bot-staging/v2alpha/docs/index.rst new file mode 100644 index 00000000..dc0a2096 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + retail_v2alpha/services + retail_v2alpha/types diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/catalog_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/catalog_service.rst new file mode 100644 index 00000000..745d0cf4 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/catalog_service.rst @@ -0,0 +1,10 @@ +CatalogService +-------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.catalog_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2alpha.services.catalog_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/completion_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/completion_service.rst new file mode 100644 index 00000000..3a276433 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/completion_service.rst @@ -0,0 +1,6 @@ +CompletionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.completion_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/control_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/control_service.rst new file mode 100644 index 00000000..36aaf9b6 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/control_service.rst @@ -0,0 +1,10 @@ +ControlService +-------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.control_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2alpha.services.control_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/merchant_center_account_link_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/merchant_center_account_link_service.rst new file mode 100644 index 00000000..df93c4f8 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/merchant_center_account_link_service.rst @@ -0,0 +1,6 @@ +MerchantCenterAccountLinkService +-------------------------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.merchant_center_account_link_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/model_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/model_service.rst new file mode 100644 index 00000000..1fbe99c7 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/model_service.rst @@ -0,0 +1,10 @@ +ModelService +------------------------------ + +.. automodule:: google.cloud.retail_v2alpha.services.model_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2alpha.services.model_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/prediction_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/prediction_service.rst new file mode 100644 index 00000000..b659cf98 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/prediction_service.rst @@ -0,0 +1,6 @@ +PredictionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.prediction_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/product_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/product_service.rst new file mode 100644 index 00000000..acbb336e --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/product_service.rst @@ -0,0 +1,10 @@ +ProductService +-------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.product_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2alpha.services.product_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/search_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/search_service.rst new file mode 100644 index 00000000..ad4c486d --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/search_service.rst @@ -0,0 +1,10 @@ +SearchService +------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.search_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2alpha.services.search_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/services.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/services.rst new file mode 100644 index 00000000..464a57dc --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/services.rst @@ -0,0 +1,15 @@ +Services for Google Cloud Retail v2alpha API +============================================ +.. toctree:: + :maxdepth: 2 + + catalog_service + completion_service + control_service + merchant_center_account_link_service + model_service + prediction_service + product_service + search_service + serving_config_service + user_event_service diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/serving_config_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/serving_config_service.rst new file mode 100644 index 00000000..c1516860 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/serving_config_service.rst @@ -0,0 +1,10 @@ +ServingConfigService +-------------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.serving_config_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2alpha.services.serving_config_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/types.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/types.rst new file mode 100644 index 00000000..bbbeb4d7 --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Retail v2alpha API +========================================= + +.. automodule:: google.cloud.retail_v2alpha.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v2alpha/docs/retail_v2alpha/user_event_service.rst b/owl-bot-staging/v2alpha/docs/retail_v2alpha/user_event_service.rst new file mode 100644 index 00000000..8c56485c --- /dev/null +++ b/owl-bot-staging/v2alpha/docs/retail_v2alpha/user_event_service.rst @@ -0,0 +1,6 @@ +UserEventService +---------------------------------- + +.. automodule:: google.cloud.retail_v2alpha.services.user_event_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2alpha/google/cloud/retail/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail/__init__.py new file mode 100644 index 00000000..7e5b45ee --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail/__init__.py @@ -0,0 +1,349 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.retail_v2alpha.services.catalog_service.client import CatalogServiceClient +from google.cloud.retail_v2alpha.services.catalog_service.async_client import CatalogServiceAsyncClient +from google.cloud.retail_v2alpha.services.completion_service.client import CompletionServiceClient +from google.cloud.retail_v2alpha.services.completion_service.async_client import CompletionServiceAsyncClient +from google.cloud.retail_v2alpha.services.control_service.client import ControlServiceClient +from google.cloud.retail_v2alpha.services.control_service.async_client import ControlServiceAsyncClient +from google.cloud.retail_v2alpha.services.merchant_center_account_link_service.client import MerchantCenterAccountLinkServiceClient +from google.cloud.retail_v2alpha.services.merchant_center_account_link_service.async_client import MerchantCenterAccountLinkServiceAsyncClient +from google.cloud.retail_v2alpha.services.model_service.client import ModelServiceClient +from google.cloud.retail_v2alpha.services.model_service.async_client import ModelServiceAsyncClient +from google.cloud.retail_v2alpha.services.prediction_service.client import PredictionServiceClient +from google.cloud.retail_v2alpha.services.prediction_service.async_client import PredictionServiceAsyncClient +from google.cloud.retail_v2alpha.services.product_service.client import ProductServiceClient +from google.cloud.retail_v2alpha.services.product_service.async_client import ProductServiceAsyncClient +from google.cloud.retail_v2alpha.services.search_service.client import SearchServiceClient +from google.cloud.retail_v2alpha.services.search_service.async_client import SearchServiceAsyncClient +from google.cloud.retail_v2alpha.services.serving_config_service.client import ServingConfigServiceClient +from google.cloud.retail_v2alpha.services.serving_config_service.async_client import ServingConfigServiceAsyncClient +from google.cloud.retail_v2alpha.services.user_event_service.client import UserEventServiceClient +from google.cloud.retail_v2alpha.services.user_event_service.async_client import UserEventServiceAsyncClient + +from google.cloud.retail_v2alpha.types.catalog import AttributesConfig +from google.cloud.retail_v2alpha.types.catalog import Catalog +from google.cloud.retail_v2alpha.types.catalog import CatalogAttribute +from google.cloud.retail_v2alpha.types.catalog import CompletionConfig +from google.cloud.retail_v2alpha.types.catalog import MerchantCenterFeedFilter +from google.cloud.retail_v2alpha.types.catalog import MerchantCenterLink +from google.cloud.retail_v2alpha.types.catalog import MerchantCenterLinkingConfig +from google.cloud.retail_v2alpha.types.catalog import ProductLevelConfig +from google.cloud.retail_v2alpha.types.catalog_service import AddCatalogAttributeRequest +from google.cloud.retail_v2alpha.types.catalog_service import BatchRemoveCatalogAttributesRequest +from google.cloud.retail_v2alpha.types.catalog_service import BatchRemoveCatalogAttributesResponse +from google.cloud.retail_v2alpha.types.catalog_service import GetAttributesConfigRequest +from google.cloud.retail_v2alpha.types.catalog_service import GetCompletionConfigRequest +from google.cloud.retail_v2alpha.types.catalog_service import GetDefaultBranchRequest +from google.cloud.retail_v2alpha.types.catalog_service import GetDefaultBranchResponse +from google.cloud.retail_v2alpha.types.catalog_service import ListCatalogsRequest +from google.cloud.retail_v2alpha.types.catalog_service import ListCatalogsResponse +from google.cloud.retail_v2alpha.types.catalog_service import RemoveCatalogAttributeRequest +from google.cloud.retail_v2alpha.types.catalog_service import ReplaceCatalogAttributeRequest +from google.cloud.retail_v2alpha.types.catalog_service import SetDefaultBranchRequest +from google.cloud.retail_v2alpha.types.catalog_service import UpdateAttributesConfigRequest +from google.cloud.retail_v2alpha.types.catalog_service import UpdateCatalogRequest +from google.cloud.retail_v2alpha.types.catalog_service import UpdateCompletionConfigRequest +from google.cloud.retail_v2alpha.types.common import Audience +from google.cloud.retail_v2alpha.types.common import ColorInfo +from google.cloud.retail_v2alpha.types.common import Condition +from google.cloud.retail_v2alpha.types.common import CustomAttribute +from google.cloud.retail_v2alpha.types.common import FulfillmentInfo +from google.cloud.retail_v2alpha.types.common import Image +from google.cloud.retail_v2alpha.types.common import Interval +from google.cloud.retail_v2alpha.types.common import LocalInventory +from google.cloud.retail_v2alpha.types.common import PriceInfo +from google.cloud.retail_v2alpha.types.common import Rating +from google.cloud.retail_v2alpha.types.common import Rule +from google.cloud.retail_v2alpha.types.common import UserInfo +from google.cloud.retail_v2alpha.types.common import AttributeConfigLevel +from google.cloud.retail_v2alpha.types.common import RecommendationsFilteringOption +from google.cloud.retail_v2alpha.types.common import SearchSolutionUseCase +from google.cloud.retail_v2alpha.types.common import SolutionType +from google.cloud.retail_v2alpha.types.completion_service import CompleteQueryRequest +from google.cloud.retail_v2alpha.types.completion_service import CompleteQueryResponse +from google.cloud.retail_v2alpha.types.control import Control +from google.cloud.retail_v2alpha.types.control_service import CreateControlRequest +from google.cloud.retail_v2alpha.types.control_service import DeleteControlRequest +from google.cloud.retail_v2alpha.types.control_service import GetControlRequest +from google.cloud.retail_v2alpha.types.control_service import ListControlsRequest +from google.cloud.retail_v2alpha.types.control_service import ListControlsResponse +from google.cloud.retail_v2alpha.types.control_service import UpdateControlRequest +from google.cloud.retail_v2alpha.types.export_config import BigQueryOutputResult +from google.cloud.retail_v2alpha.types.export_config import ExportErrorsConfig +from google.cloud.retail_v2alpha.types.export_config import ExportMetadata +from google.cloud.retail_v2alpha.types.export_config import ExportProductsResponse +from google.cloud.retail_v2alpha.types.export_config import ExportUserEventsResponse +from google.cloud.retail_v2alpha.types.export_config import GcsOutputResult +from google.cloud.retail_v2alpha.types.export_config import OutputResult +from google.cloud.retail_v2alpha.types.import_config import BigQuerySource +from google.cloud.retail_v2alpha.types.import_config import CompletionDataInputConfig +from google.cloud.retail_v2alpha.types.import_config import GcsSource +from google.cloud.retail_v2alpha.types.import_config import ImportCompletionDataRequest +from google.cloud.retail_v2alpha.types.import_config import ImportCompletionDataResponse +from google.cloud.retail_v2alpha.types.import_config import ImportErrorsConfig +from google.cloud.retail_v2alpha.types.import_config import ImportMetadata +from google.cloud.retail_v2alpha.types.import_config import ImportProductsRequest +from google.cloud.retail_v2alpha.types.import_config import ImportProductsResponse +from google.cloud.retail_v2alpha.types.import_config import ImportUserEventsRequest +from google.cloud.retail_v2alpha.types.import_config import ImportUserEventsResponse +from google.cloud.retail_v2alpha.types.import_config import ProductInlineSource +from google.cloud.retail_v2alpha.types.import_config import ProductInputConfig +from google.cloud.retail_v2alpha.types.import_config import TransformedUserEventsMetadata +from google.cloud.retail_v2alpha.types.import_config import UserEventImportSummary +from google.cloud.retail_v2alpha.types.import_config import UserEventInlineSource +from google.cloud.retail_v2alpha.types.import_config import UserEventInputConfig +from google.cloud.retail_v2alpha.types.merchant_center_account_link import CreateMerchantCenterAccountLinkMetadata +from google.cloud.retail_v2alpha.types.merchant_center_account_link import MerchantCenterAccountLink +from google.cloud.retail_v2alpha.types.merchant_center_account_link_service import CreateMerchantCenterAccountLinkRequest +from google.cloud.retail_v2alpha.types.merchant_center_account_link_service import DeleteMerchantCenterAccountLinkRequest +from google.cloud.retail_v2alpha.types.merchant_center_account_link_service import ListMerchantCenterAccountLinksRequest +from google.cloud.retail_v2alpha.types.merchant_center_account_link_service import ListMerchantCenterAccountLinksResponse +from google.cloud.retail_v2alpha.types.model import Model +from google.cloud.retail_v2alpha.types.model_service import CreateModelMetadata +from google.cloud.retail_v2alpha.types.model_service import CreateModelRequest +from google.cloud.retail_v2alpha.types.model_service import DeleteModelRequest +from google.cloud.retail_v2alpha.types.model_service import GetModelRequest +from google.cloud.retail_v2alpha.types.model_service import ListModelsRequest +from google.cloud.retail_v2alpha.types.model_service import ListModelsResponse +from google.cloud.retail_v2alpha.types.model_service import PauseModelRequest +from google.cloud.retail_v2alpha.types.model_service import ResumeModelRequest +from google.cloud.retail_v2alpha.types.model_service import TuneModelMetadata +from google.cloud.retail_v2alpha.types.model_service import TuneModelRequest +from google.cloud.retail_v2alpha.types.model_service import TuneModelResponse +from google.cloud.retail_v2alpha.types.model_service import UpdateModelRequest +from google.cloud.retail_v2alpha.types.prediction_service import PredictRequest +from google.cloud.retail_v2alpha.types.prediction_service import PredictResponse +from google.cloud.retail_v2alpha.types.product import Product +from google.cloud.retail_v2alpha.types.product_service import AddFulfillmentPlacesMetadata +from google.cloud.retail_v2alpha.types.product_service import AddFulfillmentPlacesRequest +from google.cloud.retail_v2alpha.types.product_service import AddFulfillmentPlacesResponse +from google.cloud.retail_v2alpha.types.product_service import AddLocalInventoriesMetadata +from google.cloud.retail_v2alpha.types.product_service import AddLocalInventoriesRequest +from google.cloud.retail_v2alpha.types.product_service import AddLocalInventoriesResponse +from google.cloud.retail_v2alpha.types.product_service import CreateProductRequest +from google.cloud.retail_v2alpha.types.product_service import DeleteProductRequest +from google.cloud.retail_v2alpha.types.product_service import GetProductRequest +from google.cloud.retail_v2alpha.types.product_service import ListProductsRequest +from google.cloud.retail_v2alpha.types.product_service import ListProductsResponse +from google.cloud.retail_v2alpha.types.product_service import RemoveFulfillmentPlacesMetadata +from google.cloud.retail_v2alpha.types.product_service import RemoveFulfillmentPlacesRequest +from google.cloud.retail_v2alpha.types.product_service import RemoveFulfillmentPlacesResponse +from google.cloud.retail_v2alpha.types.product_service import RemoveLocalInventoriesMetadata +from google.cloud.retail_v2alpha.types.product_service import RemoveLocalInventoriesRequest +from google.cloud.retail_v2alpha.types.product_service import RemoveLocalInventoriesResponse +from google.cloud.retail_v2alpha.types.product_service import SetInventoryMetadata +from google.cloud.retail_v2alpha.types.product_service import SetInventoryRequest +from google.cloud.retail_v2alpha.types.product_service import SetInventoryResponse +from google.cloud.retail_v2alpha.types.product_service import UpdateProductRequest +from google.cloud.retail_v2alpha.types.promotion import Promotion +from google.cloud.retail_v2alpha.types.purge_config import PurgeMetadata +from google.cloud.retail_v2alpha.types.purge_config import PurgeProductsMetadata +from google.cloud.retail_v2alpha.types.purge_config import PurgeProductsRequest +from google.cloud.retail_v2alpha.types.purge_config import PurgeProductsResponse +from google.cloud.retail_v2alpha.types.purge_config import PurgeUserEventsRequest +from google.cloud.retail_v2alpha.types.purge_config import PurgeUserEventsResponse +from google.cloud.retail_v2alpha.types.search_service import ExperimentInfo +from google.cloud.retail_v2alpha.types.search_service import SearchRequest +from google.cloud.retail_v2alpha.types.search_service import SearchResponse +from google.cloud.retail_v2alpha.types.serving_config import ServingConfig +from google.cloud.retail_v2alpha.types.serving_config_service import AddControlRequest +from google.cloud.retail_v2alpha.types.serving_config_service import CreateServingConfigRequest +from google.cloud.retail_v2alpha.types.serving_config_service import DeleteServingConfigRequest +from google.cloud.retail_v2alpha.types.serving_config_service import GetServingConfigRequest +from google.cloud.retail_v2alpha.types.serving_config_service import ListServingConfigsRequest +from google.cloud.retail_v2alpha.types.serving_config_service import ListServingConfigsResponse +from google.cloud.retail_v2alpha.types.serving_config_service import RemoveControlRequest +from google.cloud.retail_v2alpha.types.serving_config_service import UpdateServingConfigRequest +from google.cloud.retail_v2alpha.types.user_event import CompletionDetail +from google.cloud.retail_v2alpha.types.user_event import ProductDetail +from google.cloud.retail_v2alpha.types.user_event import PurchaseTransaction +from google.cloud.retail_v2alpha.types.user_event import UserEvent +from google.cloud.retail_v2alpha.types.user_event_service import CollectUserEventRequest +from google.cloud.retail_v2alpha.types.user_event_service import RejoinUserEventsMetadata +from google.cloud.retail_v2alpha.types.user_event_service import RejoinUserEventsRequest +from google.cloud.retail_v2alpha.types.user_event_service import RejoinUserEventsResponse +from google.cloud.retail_v2alpha.types.user_event_service import WriteUserEventRequest + +__all__ = ('CatalogServiceClient', + 'CatalogServiceAsyncClient', + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', + 'ControlServiceClient', + 'ControlServiceAsyncClient', + 'MerchantCenterAccountLinkServiceClient', + 'MerchantCenterAccountLinkServiceAsyncClient', + 'ModelServiceClient', + 'ModelServiceAsyncClient', + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', + 'ProductServiceClient', + 'ProductServiceAsyncClient', + 'SearchServiceClient', + 'SearchServiceAsyncClient', + 'ServingConfigServiceClient', + 'ServingConfigServiceAsyncClient', + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', + 'AttributesConfig', + 'Catalog', + 'CatalogAttribute', + 'CompletionConfig', + 'MerchantCenterFeedFilter', + 'MerchantCenterLink', + 'MerchantCenterLinkingConfig', + 'ProductLevelConfig', + 'AddCatalogAttributeRequest', + 'BatchRemoveCatalogAttributesRequest', + 'BatchRemoveCatalogAttributesResponse', + 'GetAttributesConfigRequest', + 'GetCompletionConfigRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'RemoveCatalogAttributeRequest', + 'ReplaceCatalogAttributeRequest', + 'SetDefaultBranchRequest', + 'UpdateAttributesConfigRequest', + 'UpdateCatalogRequest', + 'UpdateCompletionConfigRequest', + 'Audience', + 'ColorInfo', + 'Condition', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'LocalInventory', + 'PriceInfo', + 'Rating', + 'Rule', + 'UserInfo', + 'AttributeConfigLevel', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'SolutionType', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'Control', + 'CreateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + 'UpdateControlRequest', + 'BigQueryOutputResult', + 'ExportErrorsConfig', + 'ExportMetadata', + 'ExportProductsResponse', + 'ExportUserEventsResponse', + 'GcsOutputResult', + 'OutputResult', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'TransformedUserEventsMetadata', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'CreateMerchantCenterAccountLinkMetadata', + 'MerchantCenterAccountLink', + 'CreateMerchantCenterAccountLinkRequest', + 'DeleteMerchantCenterAccountLinkRequest', + 'ListMerchantCenterAccountLinksRequest', + 'ListMerchantCenterAccountLinksResponse', + 'Model', + 'CreateModelMetadata', + 'CreateModelRequest', + 'DeleteModelRequest', + 'GetModelRequest', + 'ListModelsRequest', + 'ListModelsResponse', + 'PauseModelRequest', + 'ResumeModelRequest', + 'TuneModelMetadata', + 'TuneModelRequest', + 'TuneModelResponse', + 'UpdateModelRequest', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'Promotion', + 'PurgeMetadata', + 'PurgeProductsMetadata', + 'PurgeProductsRequest', + 'PurgeProductsResponse', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'ExperimentInfo', + 'SearchRequest', + 'SearchResponse', + 'ServingConfig', + 'AddControlRequest', + 'CreateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'RemoveControlRequest', + 'UpdateServingConfigRequest', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail/gapic_version.py b/owl-bot-staging/v2alpha/google/cloud/retail/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail/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/v2alpha/google/cloud/retail/py.typed b/owl-bot-staging/v2alpha/google/cloud/retail/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/__init__.py new file mode 100644 index 00000000..ea0c47df --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/__init__.py @@ -0,0 +1,350 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.catalog_service import CatalogServiceClient +from .services.catalog_service import CatalogServiceAsyncClient +from .services.completion_service import CompletionServiceClient +from .services.completion_service import CompletionServiceAsyncClient +from .services.control_service import ControlServiceClient +from .services.control_service import ControlServiceAsyncClient +from .services.merchant_center_account_link_service import MerchantCenterAccountLinkServiceClient +from .services.merchant_center_account_link_service import MerchantCenterAccountLinkServiceAsyncClient +from .services.model_service import ModelServiceClient +from .services.model_service import ModelServiceAsyncClient +from .services.prediction_service import PredictionServiceClient +from .services.prediction_service import PredictionServiceAsyncClient +from .services.product_service import ProductServiceClient +from .services.product_service import ProductServiceAsyncClient +from .services.search_service import SearchServiceClient +from .services.search_service import SearchServiceAsyncClient +from .services.serving_config_service import ServingConfigServiceClient +from .services.serving_config_service import ServingConfigServiceAsyncClient +from .services.user_event_service import UserEventServiceClient +from .services.user_event_service import UserEventServiceAsyncClient + +from .types.catalog import AttributesConfig +from .types.catalog import Catalog +from .types.catalog import CatalogAttribute +from .types.catalog import CompletionConfig +from .types.catalog import MerchantCenterFeedFilter +from .types.catalog import MerchantCenterLink +from .types.catalog import MerchantCenterLinkingConfig +from .types.catalog import ProductLevelConfig +from .types.catalog_service import AddCatalogAttributeRequest +from .types.catalog_service import BatchRemoveCatalogAttributesRequest +from .types.catalog_service import BatchRemoveCatalogAttributesResponse +from .types.catalog_service import GetAttributesConfigRequest +from .types.catalog_service import GetCompletionConfigRequest +from .types.catalog_service import GetDefaultBranchRequest +from .types.catalog_service import GetDefaultBranchResponse +from .types.catalog_service import ListCatalogsRequest +from .types.catalog_service import ListCatalogsResponse +from .types.catalog_service import RemoveCatalogAttributeRequest +from .types.catalog_service import ReplaceCatalogAttributeRequest +from .types.catalog_service import SetDefaultBranchRequest +from .types.catalog_service import UpdateAttributesConfigRequest +from .types.catalog_service import UpdateCatalogRequest +from .types.catalog_service import UpdateCompletionConfigRequest +from .types.common import Audience +from .types.common import ColorInfo +from .types.common import Condition +from .types.common import CustomAttribute +from .types.common import FulfillmentInfo +from .types.common import Image +from .types.common import Interval +from .types.common import LocalInventory +from .types.common import PriceInfo +from .types.common import Rating +from .types.common import Rule +from .types.common import UserInfo +from .types.common import AttributeConfigLevel +from .types.common import RecommendationsFilteringOption +from .types.common import SearchSolutionUseCase +from .types.common import SolutionType +from .types.completion_service import CompleteQueryRequest +from .types.completion_service import CompleteQueryResponse +from .types.control import Control +from .types.control_service import CreateControlRequest +from .types.control_service import DeleteControlRequest +from .types.control_service import GetControlRequest +from .types.control_service import ListControlsRequest +from .types.control_service import ListControlsResponse +from .types.control_service import UpdateControlRequest +from .types.export_config import BigQueryOutputResult +from .types.export_config import ExportErrorsConfig +from .types.export_config import ExportMetadata +from .types.export_config import ExportProductsResponse +from .types.export_config import ExportUserEventsResponse +from .types.export_config import GcsOutputResult +from .types.export_config import OutputResult +from .types.import_config import BigQuerySource +from .types.import_config import CompletionDataInputConfig +from .types.import_config import GcsSource +from .types.import_config import ImportCompletionDataRequest +from .types.import_config import ImportCompletionDataResponse +from .types.import_config import ImportErrorsConfig +from .types.import_config import ImportMetadata +from .types.import_config import ImportProductsRequest +from .types.import_config import ImportProductsResponse +from .types.import_config import ImportUserEventsRequest +from .types.import_config import ImportUserEventsResponse +from .types.import_config import ProductInlineSource +from .types.import_config import ProductInputConfig +from .types.import_config import TransformedUserEventsMetadata +from .types.import_config import UserEventImportSummary +from .types.import_config import UserEventInlineSource +from .types.import_config import UserEventInputConfig +from .types.merchant_center_account_link import CreateMerchantCenterAccountLinkMetadata +from .types.merchant_center_account_link import MerchantCenterAccountLink +from .types.merchant_center_account_link_service import CreateMerchantCenterAccountLinkRequest +from .types.merchant_center_account_link_service import DeleteMerchantCenterAccountLinkRequest +from .types.merchant_center_account_link_service import ListMerchantCenterAccountLinksRequest +from .types.merchant_center_account_link_service import ListMerchantCenterAccountLinksResponse +from .types.model import Model +from .types.model_service import CreateModelMetadata +from .types.model_service import CreateModelRequest +from .types.model_service import DeleteModelRequest +from .types.model_service import GetModelRequest +from .types.model_service import ListModelsRequest +from .types.model_service import ListModelsResponse +from .types.model_service import PauseModelRequest +from .types.model_service import ResumeModelRequest +from .types.model_service import TuneModelMetadata +from .types.model_service import TuneModelRequest +from .types.model_service import TuneModelResponse +from .types.model_service import UpdateModelRequest +from .types.prediction_service import PredictRequest +from .types.prediction_service import PredictResponse +from .types.product import Product +from .types.product_service import AddFulfillmentPlacesMetadata +from .types.product_service import AddFulfillmentPlacesRequest +from .types.product_service import AddFulfillmentPlacesResponse +from .types.product_service import AddLocalInventoriesMetadata +from .types.product_service import AddLocalInventoriesRequest +from .types.product_service import AddLocalInventoriesResponse +from .types.product_service import CreateProductRequest +from .types.product_service import DeleteProductRequest +from .types.product_service import GetProductRequest +from .types.product_service import ListProductsRequest +from .types.product_service import ListProductsResponse +from .types.product_service import RemoveFulfillmentPlacesMetadata +from .types.product_service import RemoveFulfillmentPlacesRequest +from .types.product_service import RemoveFulfillmentPlacesResponse +from .types.product_service import RemoveLocalInventoriesMetadata +from .types.product_service import RemoveLocalInventoriesRequest +from .types.product_service import RemoveLocalInventoriesResponse +from .types.product_service import SetInventoryMetadata +from .types.product_service import SetInventoryRequest +from .types.product_service import SetInventoryResponse +from .types.product_service import UpdateProductRequest +from .types.promotion import Promotion +from .types.purge_config import PurgeMetadata +from .types.purge_config import PurgeProductsMetadata +from .types.purge_config import PurgeProductsRequest +from .types.purge_config import PurgeProductsResponse +from .types.purge_config import PurgeUserEventsRequest +from .types.purge_config import PurgeUserEventsResponse +from .types.search_service import ExperimentInfo +from .types.search_service import SearchRequest +from .types.search_service import SearchResponse +from .types.serving_config import ServingConfig +from .types.serving_config_service import AddControlRequest +from .types.serving_config_service import CreateServingConfigRequest +from .types.serving_config_service import DeleteServingConfigRequest +from .types.serving_config_service import GetServingConfigRequest +from .types.serving_config_service import ListServingConfigsRequest +from .types.serving_config_service import ListServingConfigsResponse +from .types.serving_config_service import RemoveControlRequest +from .types.serving_config_service import UpdateServingConfigRequest +from .types.user_event import CompletionDetail +from .types.user_event import ProductDetail +from .types.user_event import PurchaseTransaction +from .types.user_event import UserEvent +from .types.user_event_service import CollectUserEventRequest +from .types.user_event_service import RejoinUserEventsMetadata +from .types.user_event_service import RejoinUserEventsRequest +from .types.user_event_service import RejoinUserEventsResponse +from .types.user_event_service import WriteUserEventRequest + +__all__ = ( + 'CatalogServiceAsyncClient', + 'CompletionServiceAsyncClient', + 'ControlServiceAsyncClient', + 'MerchantCenterAccountLinkServiceAsyncClient', + 'ModelServiceAsyncClient', + 'PredictionServiceAsyncClient', + 'ProductServiceAsyncClient', + 'SearchServiceAsyncClient', + 'ServingConfigServiceAsyncClient', + 'UserEventServiceAsyncClient', +'AddCatalogAttributeRequest', +'AddControlRequest', +'AddFulfillmentPlacesMetadata', +'AddFulfillmentPlacesRequest', +'AddFulfillmentPlacesResponse', +'AddLocalInventoriesMetadata', +'AddLocalInventoriesRequest', +'AddLocalInventoriesResponse', +'AttributeConfigLevel', +'AttributesConfig', +'Audience', +'BatchRemoveCatalogAttributesRequest', +'BatchRemoveCatalogAttributesResponse', +'BigQueryOutputResult', +'BigQuerySource', +'Catalog', +'CatalogAttribute', +'CatalogServiceClient', +'CollectUserEventRequest', +'ColorInfo', +'CompleteQueryRequest', +'CompleteQueryResponse', +'CompletionConfig', +'CompletionDataInputConfig', +'CompletionDetail', +'CompletionServiceClient', +'Condition', +'Control', +'ControlServiceClient', +'CreateControlRequest', +'CreateMerchantCenterAccountLinkMetadata', +'CreateMerchantCenterAccountLinkRequest', +'CreateModelMetadata', +'CreateModelRequest', +'CreateProductRequest', +'CreateServingConfigRequest', +'CustomAttribute', +'DeleteControlRequest', +'DeleteMerchantCenterAccountLinkRequest', +'DeleteModelRequest', +'DeleteProductRequest', +'DeleteServingConfigRequest', +'ExperimentInfo', +'ExportErrorsConfig', +'ExportMetadata', +'ExportProductsResponse', +'ExportUserEventsResponse', +'FulfillmentInfo', +'GcsOutputResult', +'GcsSource', +'GetAttributesConfigRequest', +'GetCompletionConfigRequest', +'GetControlRequest', +'GetDefaultBranchRequest', +'GetDefaultBranchResponse', +'GetModelRequest', +'GetProductRequest', +'GetServingConfigRequest', +'Image', +'ImportCompletionDataRequest', +'ImportCompletionDataResponse', +'ImportErrorsConfig', +'ImportMetadata', +'ImportProductsRequest', +'ImportProductsResponse', +'ImportUserEventsRequest', +'ImportUserEventsResponse', +'Interval', +'ListCatalogsRequest', +'ListCatalogsResponse', +'ListControlsRequest', +'ListControlsResponse', +'ListMerchantCenterAccountLinksRequest', +'ListMerchantCenterAccountLinksResponse', +'ListModelsRequest', +'ListModelsResponse', +'ListProductsRequest', +'ListProductsResponse', +'ListServingConfigsRequest', +'ListServingConfigsResponse', +'LocalInventory', +'MerchantCenterAccountLink', +'MerchantCenterAccountLinkServiceClient', +'MerchantCenterFeedFilter', +'MerchantCenterLink', +'MerchantCenterLinkingConfig', +'Model', +'ModelServiceClient', +'OutputResult', +'PauseModelRequest', +'PredictRequest', +'PredictResponse', +'PredictionServiceClient', +'PriceInfo', +'Product', +'ProductDetail', +'ProductInlineSource', +'ProductInputConfig', +'ProductLevelConfig', +'ProductServiceClient', +'Promotion', +'PurchaseTransaction', +'PurgeMetadata', +'PurgeProductsMetadata', +'PurgeProductsRequest', +'PurgeProductsResponse', +'PurgeUserEventsRequest', +'PurgeUserEventsResponse', +'Rating', +'RecommendationsFilteringOption', +'RejoinUserEventsMetadata', +'RejoinUserEventsRequest', +'RejoinUserEventsResponse', +'RemoveCatalogAttributeRequest', +'RemoveControlRequest', +'RemoveFulfillmentPlacesMetadata', +'RemoveFulfillmentPlacesRequest', +'RemoveFulfillmentPlacesResponse', +'RemoveLocalInventoriesMetadata', +'RemoveLocalInventoriesRequest', +'RemoveLocalInventoriesResponse', +'ReplaceCatalogAttributeRequest', +'ResumeModelRequest', +'Rule', +'SearchRequest', +'SearchResponse', +'SearchServiceClient', +'SearchSolutionUseCase', +'ServingConfig', +'ServingConfigServiceClient', +'SetDefaultBranchRequest', +'SetInventoryMetadata', +'SetInventoryRequest', +'SetInventoryResponse', +'SolutionType', +'TransformedUserEventsMetadata', +'TuneModelMetadata', +'TuneModelRequest', +'TuneModelResponse', +'UpdateAttributesConfigRequest', +'UpdateCatalogRequest', +'UpdateCompletionConfigRequest', +'UpdateControlRequest', +'UpdateModelRequest', +'UpdateProductRequest', +'UpdateServingConfigRequest', +'UserEvent', +'UserEventImportSummary', +'UserEventInlineSource', +'UserEventInputConfig', +'UserEventServiceClient', +'UserInfo', +'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/gapic_metadata.json b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/gapic_metadata.json new file mode 100644 index 00000000..05416941 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/gapic_metadata.json @@ -0,0 +1,1039 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.retail_v2alpha", + "protoPackage": "google.cloud.retail.v2alpha", + "schema": "1.0", + "services": { + "CatalogService": { + "clients": { + "grpc": { + "libraryClient": "CatalogServiceClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CatalogServiceAsyncClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + }, + "rest": { + "libraryClient": "CatalogServiceClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + } + } + }, + "CompletionService": { + "clients": { + "grpc": { + "libraryClient": "CompletionServiceClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CompletionServiceAsyncClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + }, + "rest": { + "libraryClient": "CompletionServiceClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + } + } + }, + "ControlService": { + "clients": { + "grpc": { + "libraryClient": "ControlServiceClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ControlServiceAsyncClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + }, + "rest": { + "libraryClient": "ControlServiceClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + } + } + }, + "MerchantCenterAccountLinkService": { + "clients": { + "grpc": { + "libraryClient": "MerchantCenterAccountLinkServiceClient", + "rpcs": { + "CreateMerchantCenterAccountLink": { + "methods": [ + "create_merchant_center_account_link" + ] + }, + "DeleteMerchantCenterAccountLink": { + "methods": [ + "delete_merchant_center_account_link" + ] + }, + "ListMerchantCenterAccountLinks": { + "methods": [ + "list_merchant_center_account_links" + ] + } + } + }, + "grpc-async": { + "libraryClient": "MerchantCenterAccountLinkServiceAsyncClient", + "rpcs": { + "CreateMerchantCenterAccountLink": { + "methods": [ + "create_merchant_center_account_link" + ] + }, + "DeleteMerchantCenterAccountLink": { + "methods": [ + "delete_merchant_center_account_link" + ] + }, + "ListMerchantCenterAccountLinks": { + "methods": [ + "list_merchant_center_account_links" + ] + } + } + }, + "rest": { + "libraryClient": "MerchantCenterAccountLinkServiceClient", + "rpcs": { + "CreateMerchantCenterAccountLink": { + "methods": [ + "create_merchant_center_account_link" + ] + }, + "DeleteMerchantCenterAccountLink": { + "methods": [ + "delete_merchant_center_account_link" + ] + }, + "ListMerchantCenterAccountLinks": { + "methods": [ + "list_merchant_center_account_links" + ] + } + } + } + } + }, + "ModelService": { + "clients": { + "grpc": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ModelServiceAsyncClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "rest": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + } + } + }, + "PredictionService": { + "clients": { + "grpc": { + "libraryClient": "PredictionServiceClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + }, + "grpc-async": { + "libraryClient": "PredictionServiceAsyncClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + }, + "rest": { + "libraryClient": "PredictionServiceClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + } + } + }, + "ProductService": { + "clients": { + "grpc": { + "libraryClient": "ProductServiceClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ProductServiceAsyncClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + }, + "rest": { + "libraryClient": "ProductServiceClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "PurgeProducts": { + "methods": [ + "purge_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + } + } + }, + "SearchService": { + "clients": { + "grpc": { + "libraryClient": "SearchServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "grpc-async": { + "libraryClient": "SearchServiceAsyncClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "rest": { + "libraryClient": "SearchServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + } + } + }, + "ServingConfigService": { + "clients": { + "grpc": { + "libraryClient": "ServingConfigServiceClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ServingConfigServiceAsyncClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + }, + "rest": { + "libraryClient": "ServingConfigServiceClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + } + } + }, + "UserEventService": { + "clients": { + "grpc": { + "libraryClient": "UserEventServiceClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + }, + "grpc-async": { + "libraryClient": "UserEventServiceAsyncClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + }, + "rest": { + "libraryClient": "UserEventServiceClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/gapic_version.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/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/v2alpha/google/cloud/retail_v2alpha/py.typed b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/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/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/__init__.py new file mode 100644 index 00000000..339851f1 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/__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 CatalogServiceClient +from .async_client import CatalogServiceAsyncClient + +__all__ = ( + 'CatalogServiceClient', + 'CatalogServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/async_client.py new file mode 100644 index 00000000..0766064c --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/async_client.py @@ -0,0 +1,1613 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.catalog_service import pagers +from google.cloud.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog as gcr_catalog +from google.cloud.retail_v2alpha.types import catalog_service +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .client import CatalogServiceClient + + +class CatalogServiceAsyncClient: + """Service for managing catalog configuration.""" + + _client: CatalogServiceClient + + DEFAULT_ENDPOINT = CatalogServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CatalogServiceClient.DEFAULT_MTLS_ENDPOINT + + attributes_config_path = staticmethod(CatalogServiceClient.attributes_config_path) + parse_attributes_config_path = staticmethod(CatalogServiceClient.parse_attributes_config_path) + branch_path = staticmethod(CatalogServiceClient.branch_path) + parse_branch_path = staticmethod(CatalogServiceClient.parse_branch_path) + catalog_path = staticmethod(CatalogServiceClient.catalog_path) + parse_catalog_path = staticmethod(CatalogServiceClient.parse_catalog_path) + completion_config_path = staticmethod(CatalogServiceClient.completion_config_path) + parse_completion_config_path = staticmethod(CatalogServiceClient.parse_completion_config_path) + common_billing_account_path = staticmethod(CatalogServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CatalogServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CatalogServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CatalogServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CatalogServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CatalogServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CatalogServiceClient.common_project_path) + parse_common_project_path = staticmethod(CatalogServiceClient.parse_common_project_path) + common_location_path = staticmethod(CatalogServiceClient.common_location_path) + parse_common_location_path = staticmethod(CatalogServiceClient.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: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_info.__func__(CatalogServiceAsyncClient, 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: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_file.__func__(CatalogServiceAsyncClient, 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 CatalogServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CatalogServiceClient).get_transport_class, type(CatalogServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CatalogServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service 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, ~.CatalogServiceTransport]): 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 = CatalogServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def list_catalogs(self, + request: Optional[Union[catalog_service.ListCatalogsRequest, 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.ListCatalogsAsyncPager: + r"""Lists all the [Catalog][google.cloud.retail.v2alpha.Catalog]s + associated with the project. + + .. 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 retail_v2alpha + + async def sample_list_catalogs(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ListCatalogsRequest, dict]]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + method. + parent (:class:`str`): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2alpha.Catalog]s under + this location, regardless of whether or not this + location exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2alpha.services.catalog_service.pagers.ListCatalogsAsyncPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + 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 = catalog_service.ListCatalogsRequest(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_catalogs, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListCatalogsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_catalog(self, + request: Optional[Union[catalog_service.UpdateCatalogRequest, dict]] = None, + *, + catalog: Optional[gcr_catalog.Catalog] = 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]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2alpha.Catalog]s. + + .. 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 retail_v2alpha + + async def sample_update_catalog(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog = retail_v2alpha.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2alpha.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = await client.update_catalog(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.UpdateCatalogRequest, dict]]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2alpha.CatalogService.UpdateCatalog] + method. + catalog (:class:`google.cloud.retail_v2alpha.types.Catalog`): + Required. The + [Catalog][google.cloud.retail.v2alpha.Catalog] to + update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2alpha.Catalog], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Catalog][google.cloud.retail.v2alpha.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2alpha.Catalog] to + update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + 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.retail_v2alpha.types.Catalog: + The catalog configuration. + """ + # 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([catalog, 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 = catalog_service.UpdateCatalogRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + 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_catalog, + 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(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def set_default_branch(self, + request: Optional[Union[catalog_service.SetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + .. 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 retail_v2alpha + + async def sample_set_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.SetDefaultBranchRequest( + ) + + # Make the request + await client.set_default_branch(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.SetDefaultBranchRequest, dict]]): + The request object. Request message to set a specified branch as new + default_branch. + catalog (:class:`str`): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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([catalog]) + 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 = catalog_service.SetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_default_branch(self, + request: Optional[Union[catalog_service.GetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + .. 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 retail_v2alpha + + async def sample_get_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetDefaultBranchRequest( + ) + + # Make the request + response = await client.get_default_branch(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.GetDefaultBranchRequest, dict]]): + The request object. Request message to show which branch + is currently the default branch. + catalog (:class:`str`): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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.retail_v2alpha.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.GetDefaultBranch]. + + """ + # 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([catalog]) + 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 = catalog_service.GetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # 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_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_completion_config(self, + request: Optional[Union[catalog_service.GetCompletionConfigRequest, 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]] = (), + ) -> catalog.CompletionConfig: + r"""Gets a + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]. + + .. 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 retail_v2alpha + + async def sample_get_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.GetCompletionConfigRequest, dict]]): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2alpha.CatalogService.GetCompletionConfig] + method. + name (:class:`str`): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + + 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.retail_v2alpha.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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 = catalog_service.GetCompletionConfigRequest(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_completion_config, + 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(( + ("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_completion_config(self, + request: Optional[Union[catalog_service.UpdateCompletionConfigRequest, dict]] = None, + *, + completion_config: Optional[catalog.CompletionConfig] = 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]] = (), + ) -> catalog.CompletionConfig: + r"""Updates the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]s. + + .. 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 retail_v2alpha + + async def sample_update_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + completion_config = retail_v2alpha.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2alpha.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = await client.update_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.UpdateCompletionConfigRequest, dict]]): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2alpha.CatalogService.UpdateCompletionConfig] + method. + completion_config (:class:`google.cloud.retail_v2alpha.types.CompletionConfig`): + Required. The + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``completion_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2alpha.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2alpha.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2alpha.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2alpha.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + + 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.retail_v2alpha.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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([completion_config, 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 = catalog_service.UpdateCompletionConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if completion_config is not None: + request.completion_config = completion_config + 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_completion_config, + 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(( + ("completion_config.name", request.completion_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_attributes_config(self, + request: Optional[Union[catalog_service.GetAttributesConfigRequest, 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]] = (), + ) -> catalog.AttributesConfig: + r"""Gets an + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + .. 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 retail_v2alpha + + async def sample_get_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.GetAttributesConfigRequest, dict]]): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2alpha.CatalogService.GetAttributesConfig] + method. + name (:class:`str`): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + + 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.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # 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 = catalog_service.GetAttributesConfigRequest(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_attributes_config, + 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(( + ("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_attributes_config(self, + request: Optional[Union[catalog_service.UpdateAttributesConfigRequest, dict]] = None, + *, + attributes_config: Optional[catalog.AttributesConfig] = 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]] = (), + ) -> catalog.AttributesConfig: + r"""Updates the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + .. 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 retail_v2alpha + + async def sample_update_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + attributes_config = retail_v2alpha.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2alpha.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = await client.update_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.UpdateAttributesConfigRequest, dict]]): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2alpha.CatalogService.UpdateAttributesConfig] + method. + attributes_config (:class:`google.cloud.retail_v2alpha.types.AttributesConfig`): + Required. The + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + to update. + + This corresponds to the ``attributes_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2alpha.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + + 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.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # 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([attributes_config, 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 = catalog_service.UpdateAttributesConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if attributes_config is not None: + request.attributes_config = attributes_config + 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_attributes_config, + 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(( + ("attributes_config.name", request.attributes_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_catalog_attribute(self, + request: Optional[Union[catalog_service.AddCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Adds the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2alpha + + async def sample_add_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.AddCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.AddCatalogAttribute] + 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: + google.cloud.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.AddCatalogAttributeRequest(request) + + # 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_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_catalog_attribute(self, + request: Optional[Union[catalog_service.RemoveCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Removes the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + async def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = await client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.RemoveCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.RemoveCatalogAttribute] + 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: + google.cloud.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.RemoveCatalogAttributeRequest(request) + + # 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_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def batch_remove_catalog_attributes(self, + request: Optional[Union[catalog_service.BatchRemoveCatalogAttributesRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Removes all specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + .. 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 retail_v2alpha + + async def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = await client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesRequest, dict]]): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes] + 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: + google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes]. + + """ + # Create or coerce a protobuf request object. + request = catalog_service.BatchRemoveCatalogAttributesRequest(request) + + # 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_remove_catalog_attributes, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def replace_catalog_attribute(self, + request: Optional[Union[catalog_service.ReplaceCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Replaces the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2alpha.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + async def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ReplaceCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.ReplaceCatalogAttribute] + 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: + google.cloud.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.ReplaceCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.replace_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CatalogServiceAsyncClient": + 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__ = ( + "CatalogServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/client.py new file mode 100644 index 00000000..0b008244 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/client.py @@ -0,0 +1,1851 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.catalog_service import pagers +from google.cloud.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog as gcr_catalog +from google.cloud.retail_v2alpha.types import catalog_service +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CatalogServiceGrpcTransport +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .transports.rest import CatalogServiceRestTransport + + +class CatalogServiceClientMeta(type): + """Metaclass for the CatalogService 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[CatalogServiceTransport]] + _transport_registry["grpc"] = CatalogServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CatalogServiceGrpcAsyncIOTransport + _transport_registry["rest"] = CatalogServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[CatalogServiceTransport]: + """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 CatalogServiceClient(metaclass=CatalogServiceClientMeta): + """Service for managing catalog configuration.""" + + @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 = "retail.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: + CatalogServiceClient: 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: + CatalogServiceClient: 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) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def attributes_config_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified attributes_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/attributesConfig".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_attributes_config_path(path: str) -> Dict[str,str]: + """Parses a attributes_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/attributesConfig$", path) + return m.groupdict() if m else {} + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def completion_config_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified completion_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/completionConfig".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_completion_config_path(path: str) -> Dict[str,str]: + """Parses a completion_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/completionConfig$", 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, CatalogServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service 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, CatalogServiceTransport]): 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, CatalogServiceTransport): + # transport is a CatalogServiceTransport 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 list_catalogs(self, + request: Optional[Union[catalog_service.ListCatalogsRequest, 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.ListCatalogsPager: + r"""Lists all the [Catalog][google.cloud.retail.v2alpha.Catalog]s + associated with the project. + + .. 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 retail_v2alpha + + def sample_list_catalogs(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ListCatalogsRequest, dict]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + method. + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2alpha.Catalog]s under + this location, regardless of whether or not this + location exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2alpha.services.catalog_service.pagers.ListCatalogsPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + 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 catalog_service.ListCatalogsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.ListCatalogsRequest): + request = catalog_service.ListCatalogsRequest(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_catalogs] + + # 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.ListCatalogsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_catalog(self, + request: Optional[Union[catalog_service.UpdateCatalogRequest, dict]] = None, + *, + catalog: Optional[gcr_catalog.Catalog] = 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]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2alpha.Catalog]s. + + .. 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 retail_v2alpha + + def sample_update_catalog(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + catalog = retail_v2alpha.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2alpha.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = client.update_catalog(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.UpdateCatalogRequest, dict]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2alpha.CatalogService.UpdateCatalog] + method. + catalog (google.cloud.retail_v2alpha.types.Catalog): + Required. The + [Catalog][google.cloud.retail.v2alpha.Catalog] to + update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2alpha.Catalog], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Catalog][google.cloud.retail.v2alpha.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2alpha.Catalog] to + update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + 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.retail_v2alpha.types.Catalog: + The catalog configuration. + """ + # 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([catalog, 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 catalog_service.UpdateCatalogRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateCatalogRequest): + request = catalog_service.UpdateCatalogRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + 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_catalog] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def set_default_branch(self, + request: Optional[Union[catalog_service.SetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + .. 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 retail_v2alpha + + def sample_set_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.SetDefaultBranchRequest( + ) + + # Make the request + client.set_default_branch(request=request) + + Args: + request (Union[google.cloud.retail_v2alpha.types.SetDefaultBranchRequest, dict]): + The request object. Request message to set a specified branch as new + default_branch. + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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([catalog]) + 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 catalog_service.SetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.SetDefaultBranchRequest): + request = catalog_service.SetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_default_branch(self, + request: Optional[Union[catalog_service.GetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + .. 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 retail_v2alpha + + def sample_get_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetDefaultBranchRequest( + ) + + # Make the request + response = client.get_default_branch(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetDefaultBranchRequest, dict]): + The request object. Request message to show which branch + is currently the default branch. + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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.retail_v2alpha.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.GetDefaultBranch]. + + """ + # 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([catalog]) + 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 catalog_service.GetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetDefaultBranchRequest): + request = catalog_service.GetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_completion_config(self, + request: Optional[Union[catalog_service.GetCompletionConfigRequest, 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]] = (), + ) -> catalog.CompletionConfig: + r"""Gets a + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]. + + .. 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 retail_v2alpha + + def sample_get_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetCompletionConfigRequest, dict]): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2alpha.CatalogService.GetCompletionConfig] + method. + name (str): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + + 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.retail_v2alpha.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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 catalog_service.GetCompletionConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetCompletionConfigRequest): + request = catalog_service.GetCompletionConfigRequest(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_completion_config] + + # 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_completion_config(self, + request: Optional[Union[catalog_service.UpdateCompletionConfigRequest, dict]] = None, + *, + completion_config: Optional[catalog.CompletionConfig] = 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]] = (), + ) -> catalog.CompletionConfig: + r"""Updates the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]s. + + .. 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 retail_v2alpha + + def sample_update_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + completion_config = retail_v2alpha.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2alpha.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = client.update_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.UpdateCompletionConfigRequest, dict]): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2alpha.CatalogService.UpdateCompletionConfig] + method. + completion_config (google.cloud.retail_v2alpha.types.CompletionConfig): + Required. The + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``completion_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2alpha.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2alpha.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2alpha.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2alpha.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + + 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.retail_v2alpha.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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([completion_config, 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 catalog_service.UpdateCompletionConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateCompletionConfigRequest): + request = catalog_service.UpdateCompletionConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if completion_config is not None: + request.completion_config = completion_config + 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_completion_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("completion_config.name", request.completion_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_attributes_config(self, + request: Optional[Union[catalog_service.GetAttributesConfigRequest, 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]] = (), + ) -> catalog.AttributesConfig: + r"""Gets an + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + .. 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 retail_v2alpha + + def sample_get_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetAttributesConfigRequest, dict]): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2alpha.CatalogService.GetAttributesConfig] + method. + name (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + + 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.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # 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 catalog_service.GetAttributesConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetAttributesConfigRequest): + request = catalog_service.GetAttributesConfigRequest(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_attributes_config] + + # 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_attributes_config(self, + request: Optional[Union[catalog_service.UpdateAttributesConfigRequest, dict]] = None, + *, + attributes_config: Optional[catalog.AttributesConfig] = 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]] = (), + ) -> catalog.AttributesConfig: + r"""Updates the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + .. 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 retail_v2alpha + + def sample_update_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + attributes_config = retail_v2alpha.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2alpha.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = client.update_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.UpdateAttributesConfigRequest, dict]): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2alpha.CatalogService.UpdateAttributesConfig] + method. + attributes_config (google.cloud.retail_v2alpha.types.AttributesConfig): + Required. The + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + to update. + + This corresponds to the ``attributes_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2alpha.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + + 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.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # 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([attributes_config, 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 catalog_service.UpdateAttributesConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateAttributesConfigRequest): + request = catalog_service.UpdateAttributesConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if attributes_config is not None: + request.attributes_config = attributes_config + 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_attributes_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config.name", request.attributes_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_catalog_attribute(self, + request: Optional[Union[catalog_service.AddCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Adds the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2alpha + + def sample_add_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.AddCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.AddCatalogAttribute] + 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: + google.cloud.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.AddCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.AddCatalogAttributeRequest): + request = catalog_service.AddCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_catalog_attribute(self, + request: Optional[Union[catalog_service.RemoveCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Removes the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.RemoveCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.RemoveCatalogAttribute] + 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: + google.cloud.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.RemoveCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.RemoveCatalogAttributeRequest): + request = catalog_service.RemoveCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_remove_catalog_attributes(self, + request: Optional[Union[catalog_service.BatchRemoveCatalogAttributesRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Removes all specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + .. 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 retail_v2alpha + + def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesRequest, dict]): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes] + 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: + google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.BatchRemoveCatalogAttributesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.BatchRemoveCatalogAttributesRequest): + request = catalog_service.BatchRemoveCatalogAttributesRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_remove_catalog_attributes] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def replace_catalog_attribute(self, + request: Optional[Union[catalog_service.ReplaceCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Replaces the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2alpha.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ReplaceCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.ReplaceCatalogAttribute] + 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: + google.cloud.retail_v2alpha.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.ReplaceCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.ReplaceCatalogAttributeRequest): + request = catalog_service.ReplaceCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.replace_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CatalogServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "CatalogServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/pagers.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/pagers.py new file mode 100644 index 00000000..f6485de0 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog_service + + +class ListCatalogsPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListCatalogsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListCatalogsResponse` + 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[..., catalog_service.ListCatalogsResponse], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + 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.retail_v2alpha.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListCatalogsResponse): + 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 = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[catalog_service.ListCatalogsResponse]: + 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[catalog.Catalog]: + for page in self.pages: + yield from page.catalogs + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListCatalogsAsyncPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListCatalogsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListCatalogsResponse` + 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[catalog_service.ListCatalogsResponse]], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + 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.retail_v2alpha.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListCatalogsResponse): + 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 = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[catalog_service.ListCatalogsResponse]: + 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[catalog.Catalog]: + async def async_generator(): + async for page in self.pages: + for response in page.catalogs: + 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/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/__init__.py new file mode 100644 index 00000000..12110418 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/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 CatalogServiceTransport +from .grpc import CatalogServiceGrpcTransport +from .grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .rest import CatalogServiceRestTransport +from .rest import CatalogServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CatalogServiceTransport]] +_transport_registry['grpc'] = CatalogServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CatalogServiceGrpcAsyncIOTransport +_transport_registry['rest'] = CatalogServiceRestTransport + +__all__ = ( + 'CatalogServiceTransport', + 'CatalogServiceGrpcTransport', + 'CatalogServiceGrpcAsyncIOTransport', + 'CatalogServiceRestTransport', + 'CatalogServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/base.py new file mode 100644 index 00000000..7361bbca --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/base.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog as gcr_catalog +from google.cloud.retail_v2alpha.types import catalog_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 CatalogServiceTransport(abc.ABC): + """Abstract transport class for CatalogService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.list_catalogs: gapic_v1.method.wrap_method( + self.list_catalogs, + default_timeout=None, + client_info=client_info, + ), + self.update_catalog: gapic_v1.method.wrap_method( + self.update_catalog, + default_timeout=None, + client_info=client_info, + ), + self.set_default_branch: gapic_v1.method.wrap_method( + self.set_default_branch, + default_timeout=None, + client_info=client_info, + ), + self.get_default_branch: gapic_v1.method.wrap_method( + self.get_default_branch, + default_timeout=None, + client_info=client_info, + ), + self.get_completion_config: gapic_v1.method.wrap_method( + self.get_completion_config, + default_timeout=None, + client_info=client_info, + ), + self.update_completion_config: gapic_v1.method.wrap_method( + self.update_completion_config, + default_timeout=None, + client_info=client_info, + ), + self.get_attributes_config: gapic_v1.method.wrap_method( + self.get_attributes_config, + default_timeout=None, + client_info=client_info, + ), + self.update_attributes_config: gapic_v1.method.wrap_method( + self.update_attributes_config, + default_timeout=None, + client_info=client_info, + ), + self.add_catalog_attribute: gapic_v1.method.wrap_method( + self.add_catalog_attribute, + default_timeout=None, + client_info=client_info, + ), + self.remove_catalog_attribute: gapic_v1.method.wrap_method( + self.remove_catalog_attribute, + default_timeout=None, + client_info=client_info, + ), + self.batch_remove_catalog_attributes: gapic_v1.method.wrap_method( + self.batch_remove_catalog_attributes, + default_timeout=None, + client_info=client_info, + ), + self.replace_catalog_attribute: gapic_v1.method.wrap_method( + self.replace_catalog_attribute, + 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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Union[ + catalog_service.ListCatalogsResponse, + Awaitable[catalog_service.ListCatalogsResponse] + ]]: + raise NotImplementedError() + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Union[ + gcr_catalog.Catalog, + Awaitable[gcr_catalog.Catalog] + ]]: + raise NotImplementedError() + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Union[ + catalog_service.GetDefaultBranchResponse, + Awaitable[catalog_service.GetDefaultBranchResponse] + ]]: + raise NotImplementedError() + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + Union[ + catalog.CompletionConfig, + Awaitable[catalog.CompletionConfig] + ]]: + raise NotImplementedError() + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + Union[ + catalog.CompletionConfig, + Awaitable[catalog.CompletionConfig] + ]]: + raise NotImplementedError() + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + Union[ + catalog_service.BatchRemoveCatalogAttributesResponse, + Awaitable[catalog_service.BatchRemoveCatalogAttributesResponse] + ]]: + raise NotImplementedError() + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'CatalogServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc.py new file mode 100644 index 00000000..9ac46065 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc.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. +# +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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog as gcr_catalog +from google.cloud.retail_v2alpha.types import catalog_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO + + +class CatalogServiceGrpcTransport(CatalogServiceTransport): + """gRPC backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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 = 'retail.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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + catalog_service.ListCatalogsResponse]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2alpha.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + ~.ListCatalogsResponse]: + 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_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + gcr_catalog.Catalog]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2alpha.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + ~.Catalog]: + 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_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + empty_pb2.Empty]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + Returns: + Callable[[~.SetDefaultBranchRequest], + ~.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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + catalog_service.GetDefaultBranchResponse]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + Returns: + Callable[[~.GetDefaultBranchRequest], + ~.GetDefaultBranchResponse]: + 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_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + catalog.CompletionConfig]: + r"""Return a callable for the get completion config method over gRPC. + + Gets a + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]. + + Returns: + Callable[[~.GetCompletionConfigRequest], + ~.CompletionConfig]: + 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_completion_config' not in self._stubs: + self._stubs['get_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/GetCompletionConfig', + request_serializer=catalog_service.GetCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['get_completion_config'] + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + catalog.CompletionConfig]: + r"""Return a callable for the update completion config method over gRPC. + + Updates the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]s. + + Returns: + Callable[[~.UpdateCompletionConfigRequest], + ~.CompletionConfig]: + 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_completion_config' not in self._stubs: + self._stubs['update_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/UpdateCompletionConfig', + request_serializer=catalog_service.UpdateCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['update_completion_config'] + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + catalog.AttributesConfig]: + r"""Return a callable for the get attributes config method over gRPC. + + Gets an + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + Returns: + Callable[[~.GetAttributesConfigRequest], + ~.AttributesConfig]: + 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_attributes_config' not in self._stubs: + self._stubs['get_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/GetAttributesConfig', + request_serializer=catalog_service.GetAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['get_attributes_config'] + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + catalog.AttributesConfig]: + r"""Return a callable for the update attributes config method over gRPC. + + Updates the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + Returns: + Callable[[~.UpdateAttributesConfigRequest], + ~.AttributesConfig]: + 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_attributes_config' not in self._stubs: + self._stubs['update_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/UpdateAttributesConfig', + request_serializer=catalog_service.UpdateAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['update_attributes_config'] + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the add catalog attribute method over gRPC. + + Adds the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.AddCatalogAttributeRequest], + ~.AttributesConfig]: + 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_catalog_attribute' not in self._stubs: + self._stubs['add_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/AddCatalogAttribute', + request_serializer=catalog_service.AddCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['add_catalog_attribute'] + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the remove catalog attribute method over gRPC. + + Removes the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.RemoveCatalogAttributeRequest], + ~.AttributesConfig]: + 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_catalog_attribute' not in self._stubs: + self._stubs['remove_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/RemoveCatalogAttribute', + request_serializer=catalog_service.RemoveCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['remove_catalog_attribute'] + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + catalog_service.BatchRemoveCatalogAttributesResponse]: + r"""Return a callable for the batch remove catalog + attributes method over gRPC. + + Removes all specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + Returns: + Callable[[~.BatchRemoveCatalogAttributesRequest], + ~.BatchRemoveCatalogAttributesResponse]: + 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_remove_catalog_attributes' not in self._stubs: + self._stubs['batch_remove_catalog_attributes'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/BatchRemoveCatalogAttributes', + request_serializer=catalog_service.BatchRemoveCatalogAttributesRequest.serialize, + response_deserializer=catalog_service.BatchRemoveCatalogAttributesResponse.deserialize, + ) + return self._stubs['batch_remove_catalog_attributes'] + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the replace catalog attribute method over gRPC. + + Replaces the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2alpha.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.ReplaceCatalogAttributeRequest], + ~.AttributesConfig]: + 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 'replace_catalog_attribute' not in self._stubs: + self._stubs['replace_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/ReplaceCatalogAttribute', + request_serializer=catalog_service.ReplaceCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['replace_catalog_attribute'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'CatalogServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..4abe0855 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/grpc_asyncio.py @@ -0,0 +1,667 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog as gcr_catalog +from google.cloud.retail_v2alpha.types import catalog_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CatalogServiceGrpcTransport + + +class CatalogServiceGrpcAsyncIOTransport(CatalogServiceTransport): + """gRPC AsyncIO backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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 = 'retail.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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Awaitable[catalog_service.ListCatalogsResponse]]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2alpha.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + Awaitable[~.ListCatalogsResponse]]: + 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_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Awaitable[gcr_catalog.Catalog]]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2alpha.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + Awaitable[~.Catalog]]: + 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_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2alpha.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + Returns: + Callable[[~.SetDefaultBranchRequest], + 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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Awaitable[catalog_service.GetDefaultBranchResponse]]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + Returns: + Callable[[~.GetDefaultBranchRequest], + Awaitable[~.GetDefaultBranchResponse]]: + 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_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + Awaitable[catalog.CompletionConfig]]: + r"""Return a callable for the get completion config method over gRPC. + + Gets a + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]. + + Returns: + Callable[[~.GetCompletionConfigRequest], + Awaitable[~.CompletionConfig]]: + 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_completion_config' not in self._stubs: + self._stubs['get_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/GetCompletionConfig', + request_serializer=catalog_service.GetCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['get_completion_config'] + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + Awaitable[catalog.CompletionConfig]]: + r"""Return a callable for the update completion config method over gRPC. + + Updates the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig]s. + + Returns: + Callable[[~.UpdateCompletionConfigRequest], + Awaitable[~.CompletionConfig]]: + 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_completion_config' not in self._stubs: + self._stubs['update_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/UpdateCompletionConfig', + request_serializer=catalog_service.UpdateCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['update_completion_config'] + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the get attributes config method over gRPC. + + Gets an + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + Returns: + Callable[[~.GetAttributesConfigRequest], + Awaitable[~.AttributesConfig]]: + 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_attributes_config' not in self._stubs: + self._stubs['get_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/GetAttributesConfig', + request_serializer=catalog_service.GetAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['get_attributes_config'] + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the update attributes config method over gRPC. + + Updates the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + Returns: + Callable[[~.UpdateAttributesConfigRequest], + Awaitable[~.AttributesConfig]]: + 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_attributes_config' not in self._stubs: + self._stubs['update_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/UpdateAttributesConfig', + request_serializer=catalog_service.UpdateAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['update_attributes_config'] + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the add catalog attribute method over gRPC. + + Adds the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.AddCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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_catalog_attribute' not in self._stubs: + self._stubs['add_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/AddCatalogAttribute', + request_serializer=catalog_service.AddCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['add_catalog_attribute'] + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the remove catalog attribute method over gRPC. + + Removes the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.RemoveCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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_catalog_attribute' not in self._stubs: + self._stubs['remove_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/RemoveCatalogAttribute', + request_serializer=catalog_service.RemoveCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['remove_catalog_attribute'] + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + Awaitable[catalog_service.BatchRemoveCatalogAttributesResponse]]: + r"""Return a callable for the batch remove catalog + attributes method over gRPC. + + Removes all specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig]. + + Returns: + Callable[[~.BatchRemoveCatalogAttributesRequest], + Awaitable[~.BatchRemoveCatalogAttributesResponse]]: + 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_remove_catalog_attributes' not in self._stubs: + self._stubs['batch_remove_catalog_attributes'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/BatchRemoveCatalogAttributes', + request_serializer=catalog_service.BatchRemoveCatalogAttributesRequest.serialize, + response_deserializer=catalog_service.BatchRemoveCatalogAttributesResponse.deserialize, + ) + return self._stubs['batch_remove_catalog_attributes'] + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the replace catalog attribute method over gRPC. + + Replaces the specified + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2alpha.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.ReplaceCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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 'replace_catalog_attribute' not in self._stubs: + self._stubs['replace_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CatalogService/ReplaceCatalogAttribute', + request_serializer=catalog_service.ReplaceCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['replace_catalog_attribute'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'CatalogServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/rest.py new file mode 100644 index 00000000..fee7dd57 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/catalog_service/transports/rest.py @@ -0,0 +1,1766 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog as gcr_catalog +from google.cloud.retail_v2alpha.types import catalog_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import CatalogServiceTransport, 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 CatalogServiceRestInterceptor: + """Interceptor for CatalogService. + + 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 CatalogServiceRestTransport. + + .. code-block:: python + class MyCustomCatalogServiceInterceptor(CatalogServiceRestInterceptor): + def pre_add_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_remove_catalog_attributes(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_remove_catalog_attributes(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_attributes_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_attributes_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_completion_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_completion_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_default_branch(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_default_branch(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_catalogs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_catalogs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_replace_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_replace_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_default_branch(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_update_attributes_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_attributes_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_catalog(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_catalog(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_completion_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_completion_config(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CatalogServiceRestTransport(interceptor=MyCustomCatalogServiceInterceptor()) + client = CatalogServiceClient(transport=transport) + + + """ + def pre_add_catalog_attribute(self, request: catalog_service.AddCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.AddCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_add_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for add_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_batch_remove_catalog_attributes(self, request: catalog_service.BatchRemoveCatalogAttributesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.BatchRemoveCatalogAttributesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_remove_catalog_attributes + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_batch_remove_catalog_attributes(self, response: catalog_service.BatchRemoveCatalogAttributesResponse) -> catalog_service.BatchRemoveCatalogAttributesResponse: + """Post-rpc interceptor for batch_remove_catalog_attributes + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_attributes_config(self, request: catalog_service.GetAttributesConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetAttributesConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_attributes_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_attributes_config(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for get_attributes_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_completion_config(self, request: catalog_service.GetCompletionConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetCompletionConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_completion_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_completion_config(self, response: catalog.CompletionConfig) -> catalog.CompletionConfig: + """Post-rpc interceptor for get_completion_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_default_branch(self, request: catalog_service.GetDefaultBranchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetDefaultBranchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_default_branch + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_default_branch(self, response: catalog_service.GetDefaultBranchResponse) -> catalog_service.GetDefaultBranchResponse: + """Post-rpc interceptor for get_default_branch + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_list_catalogs(self, request: catalog_service.ListCatalogsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.ListCatalogsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_catalogs + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_list_catalogs(self, response: catalog_service.ListCatalogsResponse) -> catalog_service.ListCatalogsResponse: + """Post-rpc interceptor for list_catalogs + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_remove_catalog_attribute(self, request: catalog_service.RemoveCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.RemoveCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_remove_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for remove_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_replace_catalog_attribute(self, request: catalog_service.ReplaceCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.ReplaceCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for replace_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_replace_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for replace_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_set_default_branch(self, request: catalog_service.SetDefaultBranchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.SetDefaultBranchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_default_branch + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def pre_update_attributes_config(self, request: catalog_service.UpdateAttributesConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateAttributesConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_attributes_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_attributes_config(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for update_attributes_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_update_catalog(self, request: catalog_service.UpdateCatalogRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateCatalogRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_catalog + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_catalog(self, response: gcr_catalog.Catalog) -> gcr_catalog.Catalog: + """Post-rpc interceptor for update_catalog + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_update_completion_config(self, request: catalog_service.UpdateCompletionConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateCompletionConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_completion_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_completion_config(self, response: catalog.CompletionConfig) -> catalog.CompletionConfig: + """Post-rpc interceptor for update_completion_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CatalogServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CatalogServiceRestInterceptor + + +class CatalogServiceRestTransport(CatalogServiceTransport): + """REST backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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[CatalogServiceRestInterceptor] = 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 CatalogServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _AddCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("AddCatalogAttribute") + + __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: catalog_service.AddCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the add catalog attribute method over HTTP. + + Args: + request (~.catalog_service.AddCatalogAttributeRequest): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.AddCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:addCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_catalog_attribute(request, metadata) + pb_request = catalog_service.AddCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_add_catalog_attribute(resp) + return resp + + class _BatchRemoveCatalogAttributes(CatalogServiceRestStub): + def __hash__(self): + return hash("BatchRemoveCatalogAttributes") + + __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: catalog_service.BatchRemoveCatalogAttributesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Call the batch remove catalog + attributes method over HTTP. + + Args: + request (~.catalog_service.BatchRemoveCatalogAttributesRequest): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes] + 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: + ~.catalog_service.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes]. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:batchRemoveCatalogAttributes', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_remove_catalog_attributes(request, metadata) + pb_request = catalog_service.BatchRemoveCatalogAttributesRequest.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 = catalog_service.BatchRemoveCatalogAttributesResponse() + pb_resp = catalog_service.BatchRemoveCatalogAttributesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_remove_catalog_attributes(resp) + return resp + + class _GetAttributesConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("GetAttributesConfig") + + __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: catalog_service.GetAttributesConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the get attributes config method over HTTP. + + Args: + request (~.catalog_service.GetAttributesConfigRequest): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2alpha.CatalogService.GetAttributesConfig] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/attributesConfig}', + }, + ] + request, metadata = self._interceptor.pre_get_attributes_config(request, metadata) + pb_request = catalog_service.GetAttributesConfigRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_attributes_config(resp) + return resp + + class _GetCompletionConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("GetCompletionConfig") + + __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: catalog_service.GetCompletionConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.CompletionConfig: + r"""Call the get completion config method over HTTP. + + Args: + request (~.catalog_service.GetCompletionConfigRequest): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2alpha.CatalogService.GetCompletionConfig] + 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: + ~.catalog.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/completionConfig}', + }, + ] + request, metadata = self._interceptor.pre_get_completion_config(request, metadata) + pb_request = catalog_service.GetCompletionConfigRequest.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 = catalog.CompletionConfig() + pb_resp = catalog.CompletionConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_completion_config(resp) + return resp + + class _GetDefaultBranch(CatalogServiceRestStub): + def __hash__(self): + return hash("GetDefaultBranch") + + def __call__(self, + request: catalog_service.GetDefaultBranchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Call the get default branch method over HTTP. + + Args: + request (~.catalog_service.GetDefaultBranchRequest): + The request object. Request message to show which branch + is currently the default branch. + 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: + ~.catalog_service.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.GetDefaultBranch]. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{catalog=projects/*/locations/*/catalogs/*}:getDefaultBranch', + }, + ] + request, metadata = self._interceptor.pre_get_default_branch(request, metadata) + pb_request = catalog_service.GetDefaultBranchRequest.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["$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 = catalog_service.GetDefaultBranchResponse() + pb_resp = catalog_service.GetDefaultBranchResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_default_branch(resp) + return resp + + class _ListCatalogs(CatalogServiceRestStub): + def __hash__(self): + return hash("ListCatalogs") + + __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: catalog_service.ListCatalogsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.ListCatalogsResponse: + r"""Call the list catalogs method over HTTP. + + Args: + request (~.catalog_service.ListCatalogsRequest): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + 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: + ~.catalog_service.ListCatalogsResponse: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{parent=projects/*/locations/*}/catalogs', + }, + ] + request, metadata = self._interceptor.pre_list_catalogs(request, metadata) + pb_request = catalog_service.ListCatalogsRequest.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 = catalog_service.ListCatalogsResponse() + pb_resp = catalog_service.ListCatalogsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_catalogs(resp) + return resp + + class _RemoveCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("RemoveCatalogAttribute") + + __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: catalog_service.RemoveCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the remove catalog attribute method over HTTP. + + Args: + request (~.catalog_service.RemoveCatalogAttributeRequest): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.RemoveCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:removeCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_catalog_attribute(request, metadata) + pb_request = catalog_service.RemoveCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_remove_catalog_attribute(resp) + return resp + + class _ReplaceCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("ReplaceCatalogAttribute") + + __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: catalog_service.ReplaceCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the replace catalog attribute method over HTTP. + + Args: + request (~.catalog_service.ReplaceCatalogAttributeRequest): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.ReplaceCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:replaceCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_replace_catalog_attribute(request, metadata) + pb_request = catalog_service.ReplaceCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_replace_catalog_attribute(resp) + return resp + + class _SetDefaultBranch(CatalogServiceRestStub): + def __hash__(self): + return hash("SetDefaultBranch") + + def __call__(self, + request: catalog_service.SetDefaultBranchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the set default branch method over HTTP. + + Args: + request (~.catalog_service.SetDefaultBranchRequest): + The request object. Request message to set a specified branch as new + default_branch. + 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': '/v2alpha/{catalog=projects/*/locations/*/catalogs/*}:setDefaultBranch', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_set_default_branch(request, metadata) + pb_request = catalog_service.SetDefaultBranchRequest.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["$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 _UpdateAttributesConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateAttributesConfig") + + __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: catalog_service.UpdateAttributesConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the update attributes config method over HTTP. + + Args: + request (~.catalog_service.UpdateAttributesConfigRequest): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2alpha.CatalogService.UpdateAttributesConfig] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2alpha/{attributes_config.name=projects/*/locations/*/catalogs/*/attributesConfig}', + 'body': 'attributes_config', + }, + ] + request, metadata = self._interceptor.pre_update_attributes_config(request, metadata) + pb_request = catalog_service.UpdateAttributesConfigRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_attributes_config(resp) + return resp + + class _UpdateCatalog(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateCatalog") + + __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: catalog_service.UpdateCatalogRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_catalog.Catalog: + r"""Call the update catalog method over HTTP. + + Args: + request (~.catalog_service.UpdateCatalogRequest): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2alpha.CatalogService.UpdateCatalog] + 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: + ~.gcr_catalog.Catalog: + The catalog configuration. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2alpha/{catalog.name=projects/*/locations/*/catalogs/*}', + 'body': 'catalog', + }, + ] + request, metadata = self._interceptor.pre_update_catalog(request, metadata) + pb_request = catalog_service.UpdateCatalogRequest.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 = gcr_catalog.Catalog() + pb_resp = gcr_catalog.Catalog.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_catalog(resp) + return resp + + class _UpdateCompletionConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateCompletionConfig") + + __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: catalog_service.UpdateCompletionConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.CompletionConfig: + r"""Call the update completion config method over HTTP. + + Args: + request (~.catalog_service.UpdateCompletionConfigRequest): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2alpha.CatalogService.UpdateCompletionConfig] + 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: + ~.catalog.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2alpha/{completion_config.name=projects/*/locations/*/catalogs/*/completionConfig}', + 'body': 'completion_config', + }, + ] + request, metadata = self._interceptor.pre_update_completion_config(request, metadata) + pb_request = catalog_service.UpdateCompletionConfigRequest.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 = catalog.CompletionConfig() + pb_resp = catalog.CompletionConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_completion_config(resp) + return resp + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._AddCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + catalog_service.BatchRemoveCatalogAttributesResponse]: + # 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._BatchRemoveCatalogAttributes(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + catalog.AttributesConfig]: + # 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._GetAttributesConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + catalog.CompletionConfig]: + # 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._GetCompletionConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + catalog_service.GetDefaultBranchResponse]: + # 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._GetDefaultBranch(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + catalog_service.ListCatalogsResponse]: + # 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._ListCatalogs(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._RemoveCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._ReplaceCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + 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._SetDefaultBranch(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + catalog.AttributesConfig]: + # 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._UpdateAttributesConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + gcr_catalog.Catalog]: + # 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._UpdateCatalog(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + catalog.CompletionConfig]: + # 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._UpdateCompletionConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(CatalogServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(CatalogServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'CatalogServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/__init__.py new file mode 100644 index 00000000..440cbfb4 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/__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 CompletionServiceClient +from .async_client import CompletionServiceAsyncClient + +__all__ = ( + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/async_client.py new file mode 100644 index 00000000..4cf8288e --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/async_client.py @@ -0,0 +1,507 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import completion_service +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .client import CompletionServiceClient + + +class CompletionServiceAsyncClient: + """Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + _client: CompletionServiceClient + + DEFAULT_ENDPOINT = CompletionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CompletionServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(CompletionServiceClient.catalog_path) + parse_catalog_path = staticmethod(CompletionServiceClient.parse_catalog_path) + common_billing_account_path = staticmethod(CompletionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CompletionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CompletionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CompletionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CompletionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CompletionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CompletionServiceClient.common_project_path) + parse_common_project_path = staticmethod(CompletionServiceClient.parse_common_project_path) + common_location_path = staticmethod(CompletionServiceClient.common_location_path) + parse_common_location_path = staticmethod(CompletionServiceClient.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: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_info.__func__(CompletionServiceAsyncClient, 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: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_file.__func__(CompletionServiceAsyncClient, 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 CompletionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CompletionServiceClient).get_transport_class, type(CompletionServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CompletionServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service 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, ~.CompletionServiceTransport]): 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 = CompletionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def complete_query(self, + request: Optional[Union[completion_service.CompleteQueryRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> completion_service.CompleteQueryResponse: + r"""Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2alpha + + async def sample_complete_query(): + # Create a client + client = retail_v2alpha.CompletionServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = await client.complete_query(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CompleteQueryRequest, dict]]): + The request object. Autocomplete parameters. + 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.retail_v2alpha.types.CompleteQueryResponse: + Response of the autocomplete query. + """ + # Create or coerce a protobuf request object. + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.complete_query, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def import_completion_data(self, + request: Optional[Union[import_config.ImportCompletionDataRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2alpha + + async def sample_import_completion_data(): + # Create a client + client = retail_v2alpha.CompletionServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2alpha.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ImportCompletionDataRequest, dict]]): + The request object. Request message for + ImportCompletionData methods. + 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.retail_v2alpha.types.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2alpha.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportCompletionDataRequest(request) + + # 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_completion_data, + 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, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CompletionServiceAsyncClient": + 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__ = ( + "CompletionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/client.py new file mode 100644 index 00000000..085601b3 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/client.py @@ -0,0 +1,716 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import completion_service +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CompletionServiceGrpcTransport +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .transports.rest import CompletionServiceRestTransport + + +class CompletionServiceClientMeta(type): + """Metaclass for the CompletionService 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[CompletionServiceTransport]] + _transport_registry["grpc"] = CompletionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CompletionServiceGrpcAsyncIOTransport + _transport_registry["rest"] = CompletionServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[CompletionServiceTransport]: + """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 CompletionServiceClient(metaclass=CompletionServiceClientMeta): + """Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + @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 = "retail.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: + CompletionServiceClient: 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: + CompletionServiceClient: 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) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?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, CompletionServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service 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, CompletionServiceTransport]): 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, CompletionServiceTransport): + # transport is a CompletionServiceTransport 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 complete_query(self, + request: Optional[Union[completion_service.CompleteQueryRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> completion_service.CompleteQueryResponse: + r"""Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2alpha + + def sample_complete_query(): + # Create a client + client = retail_v2alpha.CompletionServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = client.complete_query(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CompleteQueryRequest, dict]): + The request object. Autocomplete parameters. + 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.retail_v2alpha.types.CompleteQueryResponse: + Response of the autocomplete query. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a completion_service.CompleteQueryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, completion_service.CompleteQueryRequest): + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.complete_query] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def import_completion_data(self, + request: Optional[Union[import_config.ImportCompletionDataRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2alpha + + def sample_import_completion_data(): + # Create a client + client = retail_v2alpha.CompletionServiceClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2alpha.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ImportCompletionDataRequest, dict]): + The request object. Request message for + ImportCompletionData methods. + 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.retail_v2alpha.types.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2alpha.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportCompletionDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportCompletionDataRequest): + request = import_config.ImportCompletionDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_completion_data] + + # 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, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CompletionServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "CompletionServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/__init__.py new file mode 100644 index 00000000..f32ad441 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/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 CompletionServiceTransport +from .grpc import CompletionServiceGrpcTransport +from .grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .rest import CompletionServiceRestTransport +from .rest import CompletionServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CompletionServiceTransport]] +_transport_registry['grpc'] = CompletionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CompletionServiceGrpcAsyncIOTransport +_transport_registry['rest'] = CompletionServiceRestTransport + +__all__ = ( + 'CompletionServiceTransport', + 'CompletionServiceGrpcTransport', + 'CompletionServiceGrpcAsyncIOTransport', + 'CompletionServiceRestTransport', + 'CompletionServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/base.py new file mode 100644 index 00000000..69ece70b --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/base.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import completion_service +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class CompletionServiceTransport(abc.ABC): + """Abstract transport class for CompletionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.complete_query: gapic_v1.method.wrap_method( + self.complete_query, + default_timeout=None, + client_info=client_info, + ), + self.import_completion_data: gapic_v1.method.wrap_method( + self.import_completion_data, + 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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Union[ + completion_service.CompleteQueryResponse, + Awaitable[completion_service.CompleteQueryResponse] + ]]: + raise NotImplementedError() + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'CompletionServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py new file mode 100644 index 00000000..c22fa613 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc.py @@ -0,0 +1,366 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import completion_service +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO + + +class CompletionServiceGrpcTransport(CompletionServiceTransport): + """gRPC backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + completion_service.CompleteQueryResponse]: + r"""Return a callable for the complete query method over gRPC. + + Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.CompleteQueryRequest], + ~.CompleteQueryResponse]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + operations_pb2.Operation]: + r"""Return a callable for the import completion data method over gRPC. + + Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.ImportCompletionDataRequest], + ~.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_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'CompletionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..8f55aa8a --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/grpc_asyncio.py @@ -0,0 +1,365 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import completion_service +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CompletionServiceGrpcTransport + + +class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): + """gRPC AsyncIO backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Awaitable[completion_service.CompleteQueryResponse]]: + r"""Return a callable for the complete query method over gRPC. + + Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.CompleteQueryRequest], + Awaitable[~.CompleteQueryResponse]]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import completion data method over gRPC. + + Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.ImportCompletionDataRequest], + 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_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'CompletionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py new file mode 100644 index 00000000..56b86933 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/completion_service/transports/rest.py @@ -0,0 +1,674 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import completion_service +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore + +from .base import CompletionServiceTransport, 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 CompletionServiceRestInterceptor: + """Interceptor for CompletionService. + + 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 CompletionServiceRestTransport. + + .. code-block:: python + class MyCustomCompletionServiceInterceptor(CompletionServiceRestInterceptor): + def pre_complete_query(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_complete_query(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_completion_data(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_completion_data(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CompletionServiceRestTransport(interceptor=MyCustomCompletionServiceInterceptor()) + client = CompletionServiceClient(transport=transport) + + + """ + def pre_complete_query(self, request: completion_service.CompleteQueryRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[completion_service.CompleteQueryRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for complete_query + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_complete_query(self, response: completion_service.CompleteQueryResponse) -> completion_service.CompleteQueryResponse: + """Post-rpc interceptor for complete_query + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + def pre_import_completion_data(self, request: import_config.ImportCompletionDataRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportCompletionDataRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_completion_data + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_import_completion_data(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_completion_data + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CompletionServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CompletionServiceRestInterceptor + + +class CompletionServiceRestTransport(CompletionServiceTransport): + """REST backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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[CompletionServiceRestInterceptor] = 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 CompletionServiceRestInterceptor() + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/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="v2alpha") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CompleteQuery(CompletionServiceRestStub): + def __hash__(self): + return hash("CompleteQuery") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "query" : "", } + + @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: completion_service.CompleteQueryRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> completion_service.CompleteQueryResponse: + r"""Call the complete query method over HTTP. + + Args: + request (~.completion_service.CompleteQueryRequest): + The request object. Autocomplete parameters. + 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: + ~.completion_service.CompleteQueryResponse: + Response of the autocomplete query. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{catalog=projects/*/locations/*/catalogs/*}:completeQuery', + }, + ] + request, metadata = self._interceptor.pre_complete_query(request, metadata) + pb_request = completion_service.CompleteQueryRequest.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 = completion_service.CompleteQueryResponse() + pb_resp = completion_service.CompleteQueryResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_complete_query(resp) + return resp + + class _ImportCompletionData(CompletionServiceRestStub): + def __hash__(self): + return hash("ImportCompletionData") + + __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: import_config.ImportCompletionDataRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import completion data method over HTTP. + + Args: + request (~.import_config.ImportCompletionDataRequest): + The request object. Request message for + ImportCompletionData methods. + 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/completionData:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_completion_data(request, metadata) + pb_request = import_config.ImportCompletionDataRequest.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_completion_data(resp) + return resp + + @property + def complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + completion_service.CompleteQueryResponse]: + # 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._CompleteQuery(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + 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._ImportCompletionData(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(CompletionServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(CompletionServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'CompletionServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/__init__.py new file mode 100644 index 00000000..b5539469 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/__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 ControlServiceClient +from .async_client import ControlServiceAsyncClient + +__all__ = ( + 'ControlServiceClient', + 'ControlServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/async_client.py new file mode 100644 index 00000000..9a426424 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/async_client.py @@ -0,0 +1,877 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.control_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.cloud.retail_v2alpha.types import control_service +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .client import ControlServiceClient + + +class ControlServiceAsyncClient: + """Service for modifying Control.""" + + _client: ControlServiceClient + + DEFAULT_ENDPOINT = ControlServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ControlServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ControlServiceClient.catalog_path) + parse_catalog_path = staticmethod(ControlServiceClient.parse_catalog_path) + control_path = staticmethod(ControlServiceClient.control_path) + parse_control_path = staticmethod(ControlServiceClient.parse_control_path) + common_billing_account_path = staticmethod(ControlServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ControlServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ControlServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ControlServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ControlServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ControlServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ControlServiceClient.common_project_path) + parse_common_project_path = staticmethod(ControlServiceClient.parse_common_project_path) + common_location_path = staticmethod(ControlServiceClient.common_location_path) + parse_common_location_path = staticmethod(ControlServiceClient.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: + ControlServiceAsyncClient: The constructed client. + """ + return ControlServiceClient.from_service_account_info.__func__(ControlServiceAsyncClient, 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: + ControlServiceAsyncClient: The constructed client. + """ + return ControlServiceClient.from_service_account_file.__func__(ControlServiceAsyncClient, 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 ControlServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ControlServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ControlServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ControlServiceClient).get_transport_class, type(ControlServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ControlServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the control service 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, ~.ControlServiceTransport]): 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 = ControlServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_control(self, + request: Optional[Union[control_service.CreateControlRequest, dict]] = None, + *, + parent: Optional[str] = None, + control: Optional[gcr_control.Control] = None, + control_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_control.Control: + r"""Creates a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2alpha + + async def sample_create_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = await client.create_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CreateControlRequest, dict]]): + The request object. Request for CreateControl method. + parent (:class:`str`): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control (:class:`google.cloud.retail_v2alpha.types.Control`): + Required. The Control to create. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control_id (:class:`str`): + Required. The ID to use for the Control, which will + become the final component of the Control's resource + name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``control_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.retail_v2alpha.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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, control, control_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 = control_service.CreateControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if control is not None: + request.control = control + if control_id is not None: + request.control_id = control_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_control, + 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, + ) + + # Done; return the response. + return response + + async def delete_control(self, + request: Optional[Union[control_service.DeleteControlRequest, 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"""Deletes a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to delete + does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + async def sample_delete_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteControlRequest( + name="name_value", + ) + + # Make the request + await client.delete_control(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.DeleteControlRequest, dict]]): + The request object. Request for DeleteControl method. + name (:class:`str`): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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 = control_service.DeleteControlRequest(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_control, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_control(self, + request: Optional[Union[control_service.UpdateControlRequest, dict]] = None, + *, + control: Optional[gcr_control.Control] = 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]] = (), + ) -> gcr_control.Control: + r"""Updates a Control. + + [Control][google.cloud.retail.v2alpha.Control] cannot be set to + a different oneof field, if so an INVALID_ARGUMENT is returned. + If the [Control][google.cloud.retail.v2alpha.Control] to update + does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + async def sample_update_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateControlRequest( + control=control, + ) + + # Make the request + response = await client.update_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.UpdateControlRequest, dict]]): + The request object. Request for UpdateControl method. + control (:class:`google.cloud.retail_v2alpha.types.Control`): + Required. The Control to update. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Control][google.cloud.retail.v2alpha.Control] to + update. The following are NOT supported: + + - [Control.name][google.cloud.retail.v2alpha.Control.name] + + If not set or empty, all supported fields are updated. + + 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.retail_v2alpha.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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([control, 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 = control_service.UpdateControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if control is not None: + request.control = control + 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_control, + 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(( + ("control.name", request.control.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_control(self, + request: Optional[Union[control_service.GetControlRequest, 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]] = (), + ) -> control.Control: + r"""Gets a Control. + + .. 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 retail_v2alpha + + async def sample_get_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetControlRequest( + name="name_value", + ) + + # Make the request + response = await client.get_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.GetControlRequest, dict]]): + The request object. Request for GetControl method. + name (:class:`str`): + Required. The resource name of the Control to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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.retail_v2alpha.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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 = control_service.GetControlRequest(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_control, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_controls(self, + request: Optional[Union[control_service.ListControlsRequest, 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.ListControlsAsyncPager: + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + .. 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 retail_v2alpha + + async def sample_list_controls(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ListControlsRequest, dict]]): + The request object. Request for ListControls method. + parent (:class:`str`): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2alpha.services.control_service.pagers.ListControlsAsyncPager: + Response for ListControls 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 = control_service.ListControlsRequest(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_controls, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListControlsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ControlServiceAsyncClient": + 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__ = ( + "ControlServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/client.py new file mode 100644 index 00000000..3f81e8cb --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/client.py @@ -0,0 +1,1093 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.control_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.cloud.retail_v2alpha.types import control_service +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ControlServiceGrpcTransport +from .transports.grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .transports.rest import ControlServiceRestTransport + + +class ControlServiceClientMeta(type): + """Metaclass for the ControlService 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[ControlServiceTransport]] + _transport_registry["grpc"] = ControlServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ControlServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ControlServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ControlServiceTransport]: + """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 ControlServiceClient(metaclass=ControlServiceClientMeta): + """Service for modifying Control.""" + + @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 = "retail.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: + ControlServiceClient: 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: + ControlServiceClient: 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) -> ControlServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ControlServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def control_path(project: str,location: str,catalog: str,control: str,) -> str: + """Returns a fully-qualified control string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/controls/{control}".format(project=project, location=location, catalog=catalog, control=control, ) + + @staticmethod + def parse_control_path(path: str) -> Dict[str,str]: + """Parses a control path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/controls/(?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, ControlServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the control service 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, ControlServiceTransport]): 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, ControlServiceTransport): + # transport is a ControlServiceTransport 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_control(self, + request: Optional[Union[control_service.CreateControlRequest, dict]] = None, + *, + parent: Optional[str] = None, + control: Optional[gcr_control.Control] = None, + control_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_control.Control: + r"""Creates a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2alpha + + def sample_create_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = client.create_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CreateControlRequest, dict]): + The request object. Request for CreateControl method. + parent (str): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control (google.cloud.retail_v2alpha.types.Control): + Required. The Control to create. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control_id (str): + Required. The ID to use for the Control, which will + become the final component of the Control's resource + name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``control_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.retail_v2alpha.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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, control, control_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 control_service.CreateControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.CreateControlRequest): + request = control_service.CreateControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if control is not None: + request.control = control + if control_id is not None: + request.control_id = control_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_control] + + # 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_control(self, + request: Optional[Union[control_service.DeleteControlRequest, 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"""Deletes a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to delete + does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + def sample_delete_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteControlRequest( + name="name_value", + ) + + # Make the request + client.delete_control(request=request) + + Args: + request (Union[google.cloud.retail_v2alpha.types.DeleteControlRequest, dict]): + The request object. Request for DeleteControl method. + name (str): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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 control_service.DeleteControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.DeleteControlRequest): + request = control_service.DeleteControlRequest(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_control] + + # 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 update_control(self, + request: Optional[Union[control_service.UpdateControlRequest, dict]] = None, + *, + control: Optional[gcr_control.Control] = 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]] = (), + ) -> gcr_control.Control: + r"""Updates a Control. + + [Control][google.cloud.retail.v2alpha.Control] cannot be set to + a different oneof field, if so an INVALID_ARGUMENT is returned. + If the [Control][google.cloud.retail.v2alpha.Control] to update + does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + def sample_update_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateControlRequest( + control=control, + ) + + # Make the request + response = client.update_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.UpdateControlRequest, dict]): + The request object. Request for UpdateControl method. + control (google.cloud.retail_v2alpha.types.Control): + Required. The Control to update. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Control][google.cloud.retail.v2alpha.Control] to + update. The following are NOT supported: + + - [Control.name][google.cloud.retail.v2alpha.Control.name] + + If not set or empty, all supported fields are updated. + + 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.retail_v2alpha.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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([control, 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 control_service.UpdateControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.UpdateControlRequest): + request = control_service.UpdateControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if control is not None: + request.control = control + 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_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("control.name", request.control.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_control(self, + request: Optional[Union[control_service.GetControlRequest, 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]] = (), + ) -> control.Control: + r"""Gets a Control. + + .. 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 retail_v2alpha + + def sample_get_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetControlRequest( + name="name_value", + ) + + # Make the request + response = client.get_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetControlRequest, dict]): + The request object. Request for GetControl method. + name (str): + Required. The resource name of the Control to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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.retail_v2alpha.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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 control_service.GetControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.GetControlRequest): + request = control_service.GetControlRequest(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_control] + + # 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 list_controls(self, + request: Optional[Union[control_service.ListControlsRequest, 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.ListControlsPager: + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + .. 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 retail_v2alpha + + def sample_list_controls(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ListControlsRequest, dict]): + The request object. Request for ListControls method. + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2alpha.services.control_service.pagers.ListControlsPager: + Response for ListControls 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 control_service.ListControlsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.ListControlsRequest): + request = control_service.ListControlsRequest(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_controls] + + # 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.ListControlsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ControlServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ControlServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/pagers.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/pagers.py new file mode 100644 index 00000000..c11e24f5 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control_service + + +class ListControlsPager: + """A pager for iterating through ``list_controls`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListControlsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``controls`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListControls`` requests and continue to iterate + through the ``controls`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListControlsResponse` + 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[..., control_service.ListControlsResponse], + request: control_service.ListControlsRequest, + response: control_service.ListControlsResponse, + *, + 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.retail_v2alpha.types.ListControlsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListControlsResponse): + 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 = control_service.ListControlsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[control_service.ListControlsResponse]: + 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[control.Control]: + for page in self.pages: + yield from page.controls + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListControlsAsyncPager: + """A pager for iterating through ``list_controls`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListControlsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``controls`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListControls`` requests and continue to iterate + through the ``controls`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListControlsResponse` + 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[control_service.ListControlsResponse]], + request: control_service.ListControlsRequest, + response: control_service.ListControlsResponse, + *, + 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.retail_v2alpha.types.ListControlsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListControlsResponse): + 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 = control_service.ListControlsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[control_service.ListControlsResponse]: + 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[control.Control]: + async def async_generator(): + async for page in self.pages: + for response in page.controls: + 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/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/__init__.py new file mode 100644 index 00000000..103fc931 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/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 ControlServiceTransport +from .grpc import ControlServiceGrpcTransport +from .grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .rest import ControlServiceRestTransport +from .rest import ControlServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ControlServiceTransport]] +_transport_registry['grpc'] = ControlServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ControlServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ControlServiceRestTransport + +__all__ = ( + 'ControlServiceTransport', + 'ControlServiceGrpcTransport', + 'ControlServiceGrpcAsyncIOTransport', + 'ControlServiceRestTransport', + 'ControlServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/base.py new file mode 100644 index 00000000..ddedea73 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/base.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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.cloud.retail_v2alpha.types import control_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 ControlServiceTransport(abc.ABC): + """Abstract transport class for ControlService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_control: gapic_v1.method.wrap_method( + self.create_control, + default_timeout=None, + client_info=client_info, + ), + self.delete_control: gapic_v1.method.wrap_method( + self.delete_control, + default_timeout=None, + client_info=client_info, + ), + self.update_control: gapic_v1.method.wrap_method( + self.update_control, + default_timeout=None, + client_info=client_info, + ), + self.get_control: gapic_v1.method.wrap_method( + self.get_control, + default_timeout=None, + client_info=client_info, + ), + self.list_controls: gapic_v1.method.wrap_method( + self.list_controls, + 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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + Union[ + gcr_control.Control, + Awaitable[gcr_control.Control] + ]]: + raise NotImplementedError() + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + Union[ + gcr_control.Control, + Awaitable[gcr_control.Control] + ]]: + raise NotImplementedError() + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + Union[ + control.Control, + Awaitable[control.Control] + ]]: + raise NotImplementedError() + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + Union[ + control_service.ListControlsResponse, + Awaitable[control_service.ListControlsResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ControlServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc.py new file mode 100644 index 00000000..b6fbf6db --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.cloud.retail_v2alpha.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ControlServiceTransport, DEFAULT_CLIENT_INFO + + +class ControlServiceGrpcTransport(ControlServiceTransport): + """gRPC backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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 = 'retail.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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + gcr_control.Control]: + r"""Return a callable for the create control method over gRPC. + + Creates a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.CreateControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['create_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/CreateControl', + request_serializer=control_service.CreateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['create_control'] + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete control method over gRPC. + + Deletes a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to delete + does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteControlRequest], + ~.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_control' not in self._stubs: + self._stubs['delete_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/DeleteControl', + request_serializer=control_service.DeleteControlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_control'] + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + gcr_control.Control]: + r"""Return a callable for the update control method over gRPC. + + Updates a Control. + + [Control][google.cloud.retail.v2alpha.Control] cannot be set to + a different oneof field, if so an INVALID_ARGUMENT is returned. + If the [Control][google.cloud.retail.v2alpha.Control] to update + does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.UpdateControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['update_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/UpdateControl', + request_serializer=control_service.UpdateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['update_control'] + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + control.Control]: + r"""Return a callable for the get control method over gRPC. + + Gets a Control. + + Returns: + Callable[[~.GetControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['get_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/GetControl', + request_serializer=control_service.GetControlRequest.serialize, + response_deserializer=control.Control.deserialize, + ) + return self._stubs['get_control'] + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + control_service.ListControlsResponse]: + r"""Return a callable for the list controls method over gRPC. + + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + Returns: + Callable[[~.ListControlsRequest], + ~.ListControlsResponse]: + 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_controls' not in self._stubs: + self._stubs['list_controls'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/ListControls', + request_serializer=control_service.ListControlsRequest.serialize, + response_deserializer=control_service.ListControlsResponse.deserialize, + ) + return self._stubs['list_controls'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ControlServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..b115a184 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/grpc_asyncio.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.cloud.retail_v2alpha.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ControlServiceGrpcTransport + + +class ControlServiceGrpcAsyncIOTransport(ControlServiceTransport): + """gRPC AsyncIO backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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 = 'retail.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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + Awaitable[gcr_control.Control]]: + r"""Return a callable for the create control method over gRPC. + + Creates a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.CreateControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['create_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/CreateControl', + request_serializer=control_service.CreateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['create_control'] + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete control method over gRPC. + + Deletes a Control. + + If the [Control][google.cloud.retail.v2alpha.Control] to delete + does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteControlRequest], + 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_control' not in self._stubs: + self._stubs['delete_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/DeleteControl', + request_serializer=control_service.DeleteControlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_control'] + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + Awaitable[gcr_control.Control]]: + r"""Return a callable for the update control method over gRPC. + + Updates a Control. + + [Control][google.cloud.retail.v2alpha.Control] cannot be set to + a different oneof field, if so an INVALID_ARGUMENT is returned. + If the [Control][google.cloud.retail.v2alpha.Control] to update + does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.UpdateControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['update_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/UpdateControl', + request_serializer=control_service.UpdateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['update_control'] + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + Awaitable[control.Control]]: + r"""Return a callable for the get control method over gRPC. + + Gets a Control. + + Returns: + Callable[[~.GetControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['get_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/GetControl', + request_serializer=control_service.GetControlRequest.serialize, + response_deserializer=control.Control.deserialize, + ) + return self._stubs['get_control'] + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + Awaitable[control_service.ListControlsResponse]]: + r"""Return a callable for the list controls method over gRPC. + + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + Returns: + Callable[[~.ListControlsRequest], + Awaitable[~.ListControlsResponse]]: + 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_controls' not in self._stubs: + self._stubs['list_controls'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ControlService/ListControls', + request_serializer=control_service.ListControlsRequest.serialize, + response_deserializer=control_service.ListControlsResponse.deserialize, + ) + return self._stubs['list_controls'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ControlServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/rest.py new file mode 100644 index 00000000..a798f856 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/control_service/transports/rest.py @@ -0,0 +1,934 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.cloud.retail_v2alpha.types import control_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ControlServiceTransport, 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 ControlServiceRestInterceptor: + """Interceptor for ControlService. + + 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 ControlServiceRestTransport. + + .. code-block:: python + class MyCustomControlServiceInterceptor(ControlServiceRestInterceptor): + def pre_create_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_controls(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_controls(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_control(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ControlServiceRestTransport(interceptor=MyCustomControlServiceInterceptor()) + client = ControlServiceClient(transport=transport) + + + """ + def pre_create_control(self, request: control_service.CreateControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.CreateControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_create_control(self, response: gcr_control.Control) -> gcr_control.Control: + """Post-rpc interceptor for create_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_delete_control(self, request: control_service.DeleteControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.DeleteControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def pre_get_control(self, request: control_service.GetControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.GetControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_get_control(self, response: control.Control) -> control.Control: + """Post-rpc interceptor for get_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_list_controls(self, request: control_service.ListControlsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.ListControlsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_controls + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_list_controls(self, response: control_service.ListControlsResponse) -> control_service.ListControlsResponse: + """Post-rpc interceptor for list_controls + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_update_control(self, request: control_service.UpdateControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.UpdateControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_update_control(self, response: gcr_control.Control) -> gcr_control.Control: + """Post-rpc interceptor for update_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ControlServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ControlServiceRestInterceptor + + +class ControlServiceRestTransport(ControlServiceTransport): + """REST backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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[ControlServiceRestInterceptor] = 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 ControlServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _CreateControl(ControlServiceRestStub): + def __hash__(self): + return hash("CreateControl") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "controlId" : "", } + + @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: control_service.CreateControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_control.Control: + r"""Call the create control method over HTTP. + + Args: + request (~.control_service.CreateControlRequest): + The request object. Request for CreateControl 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: + ~.gcr_control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/controls', + 'body': 'control', + }, + ] + request, metadata = self._interceptor.pre_create_control(request, metadata) + pb_request = control_service.CreateControlRequest.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 = gcr_control.Control() + pb_resp = gcr_control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_control(resp) + return resp + + class _DeleteControl(ControlServiceRestStub): + def __hash__(self): + return hash("DeleteControl") + + __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: control_service.DeleteControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete control method over HTTP. + + Args: + request (~.control_service.DeleteControlRequest): + The request object. Request for DeleteControl 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/controls/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_control(request, metadata) + pb_request = control_service.DeleteControlRequest.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 _GetControl(ControlServiceRestStub): + def __hash__(self): + return hash("GetControl") + + __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: control_service.GetControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> control.Control: + r"""Call the get control method over HTTP. + + Args: + request (~.control_service.GetControlRequest): + The request object. Request for GetControl 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: + ~.control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/controls/*}', + }, + ] + request, metadata = self._interceptor.pre_get_control(request, metadata) + pb_request = control_service.GetControlRequest.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 = control.Control() + pb_resp = control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_control(resp) + return resp + + class _ListControls(ControlServiceRestStub): + def __hash__(self): + return hash("ListControls") + + __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: control_service.ListControlsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> control_service.ListControlsResponse: + r"""Call the list controls method over HTTP. + + Args: + request (~.control_service.ListControlsRequest): + The request object. Request for ListControls 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: + ~.control_service.ListControlsResponse: + Response for ListControls method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/controls', + }, + ] + request, metadata = self._interceptor.pre_list_controls(request, metadata) + pb_request = control_service.ListControlsRequest.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 = control_service.ListControlsResponse() + pb_resp = control_service.ListControlsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_controls(resp) + return resp + + class _UpdateControl(ControlServiceRestStub): + def __hash__(self): + return hash("UpdateControl") + + __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: control_service.UpdateControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_control.Control: + r"""Call the update control method over HTTP. + + Args: + request (~.control_service.UpdateControlRequest): + The request object. Request for UpdateControl 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: + ~.gcr_control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2alpha/{control.name=projects/*/locations/*/catalogs/*/controls/*}', + 'body': 'control', + }, + ] + request, metadata = self._interceptor.pre_update_control(request, metadata) + pb_request = control_service.UpdateControlRequest.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 = gcr_control.Control() + pb_resp = gcr_control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_control(resp) + return resp + + @property + def create_control(self) -> Callable[ + [control_service.CreateControlRequest], + gcr_control.Control]: + # 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._CreateControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + 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._DeleteControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + control.Control]: + # 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._GetControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + control_service.ListControlsResponse]: + # 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._ListControls(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + gcr_control.Control]: + # 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._UpdateControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ControlServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ControlServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ControlServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/__init__.py new file mode 100644 index 00000000..e955c332 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/__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 MerchantCenterAccountLinkServiceClient +from .async_client import MerchantCenterAccountLinkServiceAsyncClient + +__all__ = ( + 'MerchantCenterAccountLinkServiceClient', + 'MerchantCenterAccountLinkServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/async_client.py new file mode 100644 index 00000000..25cd29b8 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/async_client.py @@ -0,0 +1,651 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import merchant_center_account_link +from google.cloud.retail_v2alpha.types import merchant_center_account_link as gcr_merchant_center_account_link +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import MerchantCenterAccountLinkServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import MerchantCenterAccountLinkServiceGrpcAsyncIOTransport +from .client import MerchantCenterAccountLinkServiceClient + + +class MerchantCenterAccountLinkServiceAsyncClient: + """Merchant Center Link service to link a Branch to a Merchant + Center Account. + """ + + _client: MerchantCenterAccountLinkServiceClient + + DEFAULT_ENDPOINT = MerchantCenterAccountLinkServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = MerchantCenterAccountLinkServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(MerchantCenterAccountLinkServiceClient.catalog_path) + parse_catalog_path = staticmethod(MerchantCenterAccountLinkServiceClient.parse_catalog_path) + merchant_center_account_link_path = staticmethod(MerchantCenterAccountLinkServiceClient.merchant_center_account_link_path) + parse_merchant_center_account_link_path = staticmethod(MerchantCenterAccountLinkServiceClient.parse_merchant_center_account_link_path) + common_billing_account_path = staticmethod(MerchantCenterAccountLinkServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(MerchantCenterAccountLinkServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(MerchantCenterAccountLinkServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(MerchantCenterAccountLinkServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(MerchantCenterAccountLinkServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(MerchantCenterAccountLinkServiceClient.parse_common_organization_path) + common_project_path = staticmethod(MerchantCenterAccountLinkServiceClient.common_project_path) + parse_common_project_path = staticmethod(MerchantCenterAccountLinkServiceClient.parse_common_project_path) + common_location_path = staticmethod(MerchantCenterAccountLinkServiceClient.common_location_path) + parse_common_location_path = staticmethod(MerchantCenterAccountLinkServiceClient.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: + MerchantCenterAccountLinkServiceAsyncClient: The constructed client. + """ + return MerchantCenterAccountLinkServiceClient.from_service_account_info.__func__(MerchantCenterAccountLinkServiceAsyncClient, 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: + MerchantCenterAccountLinkServiceAsyncClient: The constructed client. + """ + return MerchantCenterAccountLinkServiceClient.from_service_account_file.__func__(MerchantCenterAccountLinkServiceAsyncClient, 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 MerchantCenterAccountLinkServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> MerchantCenterAccountLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MerchantCenterAccountLinkServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(MerchantCenterAccountLinkServiceClient).get_transport_class, type(MerchantCenterAccountLinkServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, MerchantCenterAccountLinkServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the merchant center account link service 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, ~.MerchantCenterAccountLinkServiceTransport]): 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 = MerchantCenterAccountLinkServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def list_merchant_center_account_links(self, + request: Optional[Union[merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, 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]] = (), + ) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + r"""Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + .. 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 retail_v2alpha + + async def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = await client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest, dict]]): + The request object. Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + parent (:class:`str`): + Required. The parent Catalog of the resource. It must + match this format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_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.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse: + Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + """ + # 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 = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(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_merchant_center_account_links, + 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, + ) + + # Done; return the response. + return response + + async def create_merchant_center_account_link(self, + request: Optional[Union[merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, dict]] = None, + *, + parent: Optional[str] = None, + merchant_center_account_link: Optional[gcr_merchant_center_account_link.MerchantCenterAccountLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + + .. 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 retail_v2alpha + + async def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest, dict]]): + The request object. Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + method. + parent (:class:`str`): + Required. The branch resource where this + MerchantCenterAccountLink will be created. Format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID}} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + merchant_center_account_link (:class:`google.cloud.retail_v2alpha.types.MerchantCenterAccountLink`): + Required. The + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to create. + + If the caller does not have permission to create the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This corresponds to the ``merchant_center_account_link`` 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.retail_v2alpha.types.MerchantCenterAccountLink` Represents a link between a Merchant Center account and a branch. + Once a link is established, products from the linked + merchant center account will be streamed to the + linked branch. + + """ + # 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, merchant_center_account_link]) + 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 = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if merchant_center_account_link is not None: + request.merchant_center_account_link = merchant_center_account_link + + # 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_merchant_center_account_link, + 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, + gcr_merchant_center_account_link.MerchantCenterAccountLink, + metadata_type=gcr_merchant_center_account_link.CreateMerchantCenterAccountLinkMetadata, + ) + + # Done; return the response. + return response + + async def delete_merchant_center_account_link(self, + request: Optional[Union[merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, 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"""Deletes a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + async def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + await client.delete_merchant_center_account_link(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest, dict]]): + The request object. Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + method. + name (:class:`str`): + Required. Full resource name. Format: + projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/merchantCenterAccountLinks/{merchant_center_account_link_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 = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(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_merchant_center_account_link, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "MerchantCenterAccountLinkServiceAsyncClient": + 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__ = ( + "MerchantCenterAccountLinkServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/client.py new file mode 100644 index 00000000..bb12b8ee --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/client.py @@ -0,0 +1,867 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import merchant_center_account_link +from google.cloud.retail_v2alpha.types import merchant_center_account_link as gcr_merchant_center_account_link +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import MerchantCenterAccountLinkServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import MerchantCenterAccountLinkServiceGrpcTransport +from .transports.grpc_asyncio import MerchantCenterAccountLinkServiceGrpcAsyncIOTransport +from .transports.rest import MerchantCenterAccountLinkServiceRestTransport + + +class MerchantCenterAccountLinkServiceClientMeta(type): + """Metaclass for the MerchantCenterAccountLinkService 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[MerchantCenterAccountLinkServiceTransport]] + _transport_registry["grpc"] = MerchantCenterAccountLinkServiceGrpcTransport + _transport_registry["grpc_asyncio"] = MerchantCenterAccountLinkServiceGrpcAsyncIOTransport + _transport_registry["rest"] = MerchantCenterAccountLinkServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[MerchantCenterAccountLinkServiceTransport]: + """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 MerchantCenterAccountLinkServiceClient(metaclass=MerchantCenterAccountLinkServiceClientMeta): + """Merchant Center Link service to link a Branch to a Merchant + Center Account. + """ + + @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 = "retail.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: + MerchantCenterAccountLinkServiceClient: 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: + MerchantCenterAccountLinkServiceClient: 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) -> MerchantCenterAccountLinkServiceTransport: + """Returns the transport used by the client instance. + + Returns: + MerchantCenterAccountLinkServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def merchant_center_account_link_path(project: str,location: str,catalog: str,merchant_center_account_link: str,) -> str: + """Returns a fully-qualified merchant_center_account_link string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/merchantCenterAccountLinks/{merchant_center_account_link}".format(project=project, location=location, catalog=catalog, merchant_center_account_link=merchant_center_account_link, ) + + @staticmethod + def parse_merchant_center_account_link_path(path: str) -> Dict[str,str]: + """Parses a merchant_center_account_link path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/merchantCenterAccountLinks/(?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, MerchantCenterAccountLinkServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the merchant center account link service 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, MerchantCenterAccountLinkServiceTransport]): 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, MerchantCenterAccountLinkServiceTransport): + # transport is a MerchantCenterAccountLinkServiceTransport 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 list_merchant_center_account_links(self, + request: Optional[Union[merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, 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]] = (), + ) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + r"""Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + .. 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 retail_v2alpha + + def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest, dict]): + The request object. Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + parent (str): + Required. The parent Catalog of the resource. It must + match this format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_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.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse: + Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + """ + # 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 merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest): + request = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(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_merchant_center_account_links] + + # 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 create_merchant_center_account_link(self, + request: Optional[Union[merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, dict]] = None, + *, + parent: Optional[str] = None, + merchant_center_account_link: Optional[gcr_merchant_center_account_link.MerchantCenterAccountLink] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + + .. 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 retail_v2alpha + + def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest, dict]): + The request object. Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + method. + parent (str): + Required. The branch resource where this + MerchantCenterAccountLink will be created. Format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID}} + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + merchant_center_account_link (google.cloud.retail_v2alpha.types.MerchantCenterAccountLink): + Required. The + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to create. + + If the caller does not have permission to create the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This corresponds to the ``merchant_center_account_link`` 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.retail_v2alpha.types.MerchantCenterAccountLink` Represents a link between a Merchant Center account and a branch. + Once a link is established, products from the linked + merchant center account will be streamed to the + linked branch. + + """ + # 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, merchant_center_account_link]) + 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 merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest): + request = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if merchant_center_account_link is not None: + request.merchant_center_account_link = merchant_center_account_link + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_merchant_center_account_link] + + # 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, + gcr_merchant_center_account_link.MerchantCenterAccountLink, + metadata_type=gcr_merchant_center_account_link.CreateMerchantCenterAccountLinkMetadata, + ) + + # Done; return the response. + return response + + def delete_merchant_center_account_link(self, + request: Optional[Union[merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, 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"""Deletes a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2alpha + + def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + client.delete_merchant_center_account_link(request=request) + + Args: + request (Union[google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest, dict]): + The request object. Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + method. + name (str): + Required. Full resource name. Format: + projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/merchantCenterAccountLinks/{merchant_center_account_link_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 merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest): + request = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(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_merchant_center_account_link] + + # 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 __enter__(self) -> "MerchantCenterAccountLinkServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "MerchantCenterAccountLinkServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/__init__.py new file mode 100644 index 00000000..e9619f17 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/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 MerchantCenterAccountLinkServiceTransport +from .grpc import MerchantCenterAccountLinkServiceGrpcTransport +from .grpc_asyncio import MerchantCenterAccountLinkServiceGrpcAsyncIOTransport +from .rest import MerchantCenterAccountLinkServiceRestTransport +from .rest import MerchantCenterAccountLinkServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[MerchantCenterAccountLinkServiceTransport]] +_transport_registry['grpc'] = MerchantCenterAccountLinkServiceGrpcTransport +_transport_registry['grpc_asyncio'] = MerchantCenterAccountLinkServiceGrpcAsyncIOTransport +_transport_registry['rest'] = MerchantCenterAccountLinkServiceRestTransport + +__all__ = ( + 'MerchantCenterAccountLinkServiceTransport', + 'MerchantCenterAccountLinkServiceGrpcTransport', + 'MerchantCenterAccountLinkServiceGrpcAsyncIOTransport', + 'MerchantCenterAccountLinkServiceRestTransport', + 'MerchantCenterAccountLinkServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/base.py new file mode 100644 index 00000000..a6f187fd --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/base.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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import merchant_center_account_link_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 MerchantCenterAccountLinkServiceTransport(abc.ABC): + """Abstract transport class for MerchantCenterAccountLinkService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.list_merchant_center_account_links: gapic_v1.method.wrap_method( + self.list_merchant_center_account_links, + default_timeout=None, + client_info=client_info, + ), + self.create_merchant_center_account_link: gapic_v1.method.wrap_method( + self.create_merchant_center_account_link, + default_timeout=None, + client_info=client_info, + ), + self.delete_merchant_center_account_link: gapic_v1.method.wrap_method( + self.delete_merchant_center_account_link, + 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 list_merchant_center_account_links(self) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + Union[ + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse, + Awaitable[merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse] + ]]: + raise NotImplementedError() + + @property + def create_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def delete_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'MerchantCenterAccountLinkServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc.py new file mode 100644 index 00000000..fdbd3f0b --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc.py @@ -0,0 +1,385 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import MerchantCenterAccountLinkServiceTransport, DEFAULT_CLIENT_INFO + + +class MerchantCenterAccountLinkServiceGrpcTransport(MerchantCenterAccountLinkServiceTransport): + """gRPC backend transport for MerchantCenterAccountLinkService. + + Merchant Center Link service to link a Branch to a Merchant + Center Account. + + 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 = 'retail.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 = 'retail.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 list_merchant_center_account_links(self) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse]: + r"""Return a callable for the list merchant center account + links method over gRPC. + + Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + Returns: + Callable[[~.ListMerchantCenterAccountLinksRequest], + ~.ListMerchantCenterAccountLinksResponse]: + 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_merchant_center_account_links' not in self._stubs: + self._stubs['list_merchant_center_account_links'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/ListMerchantCenterAccountLinks', + request_serializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.serialize, + response_deserializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.deserialize, + ) + return self._stubs['list_merchant_center_account_links'] + + @property + def create_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + operations_pb2.Operation]: + r"""Return a callable for the create merchant center account + link method over gRPC. + + Creates a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + + Returns: + Callable[[~.CreateMerchantCenterAccountLinkRequest], + ~.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 'create_merchant_center_account_link' not in self._stubs: + self._stubs['create_merchant_center_account_link'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/CreateMerchantCenterAccountLink', + request_serializer=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_merchant_center_account_link'] + + @property + def delete_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete merchant center account + link method over gRPC. + + Deletes a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteMerchantCenterAccountLinkRequest], + ~.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_merchant_center_account_link' not in self._stubs: + self._stubs['delete_merchant_center_account_link'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/DeleteMerchantCenterAccountLink', + request_serializer=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_merchant_center_account_link'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'MerchantCenterAccountLinkServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..53084670 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/grpc_asyncio.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import MerchantCenterAccountLinkServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import MerchantCenterAccountLinkServiceGrpcTransport + + +class MerchantCenterAccountLinkServiceGrpcAsyncIOTransport(MerchantCenterAccountLinkServiceTransport): + """gRPC AsyncIO backend transport for MerchantCenterAccountLinkService. + + Merchant Center Link service to link a Branch to a Merchant + Center Account. + + 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 = 'retail.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 = 'retail.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 list_merchant_center_account_links(self) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + Awaitable[merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse]]: + r"""Return a callable for the list merchant center account + links method over gRPC. + + Lists all + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]s + under the specified parent + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + Returns: + Callable[[~.ListMerchantCenterAccountLinksRequest], + Awaitable[~.ListMerchantCenterAccountLinksResponse]]: + 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_merchant_center_account_links' not in self._stubs: + self._stubs['list_merchant_center_account_links'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/ListMerchantCenterAccountLinks', + request_serializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.serialize, + response_deserializer=merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.deserialize, + ) + return self._stubs['list_merchant_center_account_links'] + + @property + def create_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the create merchant center account + link method over gRPC. + + Creates a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + + Returns: + Callable[[~.CreateMerchantCenterAccountLinkRequest], + 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 'create_merchant_center_account_link' not in self._stubs: + self._stubs['create_merchant_center_account_link'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/CreateMerchantCenterAccountLink', + request_serializer=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_merchant_center_account_link'] + + @property + def delete_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete merchant center account + link method over gRPC. + + Deletes a + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink]. + If the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to delete does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteMerchantCenterAccountLinkRequest], + 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_merchant_center_account_link' not in self._stubs: + self._stubs['delete_merchant_center_account_link'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.MerchantCenterAccountLinkService/DeleteMerchantCenterAccountLink', + request_serializer=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_merchant_center_account_link'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'MerchantCenterAccountLinkServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/rest.py new file mode 100644 index 00000000..efee7dce --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/merchant_center_account_link_service/transports/rest.py @@ -0,0 +1,768 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import merchant_center_account_link_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import MerchantCenterAccountLinkServiceTransport, 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 MerchantCenterAccountLinkServiceRestInterceptor: + """Interceptor for MerchantCenterAccountLinkService. + + 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 MerchantCenterAccountLinkServiceRestTransport. + + .. code-block:: python + class MyCustomMerchantCenterAccountLinkServiceInterceptor(MerchantCenterAccountLinkServiceRestInterceptor): + def pre_create_merchant_center_account_link(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_merchant_center_account_link(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_merchant_center_account_link(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_list_merchant_center_account_links(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_merchant_center_account_links(self, response): + logging.log(f"Received response: {response}") + return response + + transport = MerchantCenterAccountLinkServiceRestTransport(interceptor=MyCustomMerchantCenterAccountLinkServiceInterceptor()) + client = MerchantCenterAccountLinkServiceClient(transport=transport) + + + """ + def pre_create_merchant_center_account_link(self, request: merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_merchant_center_account_link + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_create_merchant_center_account_link(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for create_merchant_center_account_link + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + def pre_delete_merchant_center_account_link(self, request: merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_merchant_center_account_link + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def pre_list_merchant_center_account_links(self, request: merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_merchant_center_account_links + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_list_merchant_center_account_links(self, response: merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + """Post-rpc interceptor for list_merchant_center_account_links + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the MerchantCenterAccountLinkService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the MerchantCenterAccountLinkService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class MerchantCenterAccountLinkServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: MerchantCenterAccountLinkServiceRestInterceptor + + +class MerchantCenterAccountLinkServiceRestTransport(MerchantCenterAccountLinkServiceTransport): + """REST backend transport for MerchantCenterAccountLinkService. + + Merchant Center Link service to link a Branch to a Merchant + Center Account. + + 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 = 'retail.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[MerchantCenterAccountLinkServiceRestInterceptor] = 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 MerchantCenterAccountLinkServiceRestInterceptor() + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/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="v2alpha") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CreateMerchantCenterAccountLink(MerchantCenterAccountLinkServiceRestStub): + def __hash__(self): + return hash("CreateMerchantCenterAccountLink") + + __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: merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the create merchant center + account link method over HTTP. + + Args: + request (~.merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest): + The request object. Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/merchantCenterAccountLinks', + 'body': 'merchant_center_account_link', + }, + ] + request, metadata = self._interceptor.pre_create_merchant_center_account_link(request, metadata) + pb_request = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.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_create_merchant_center_account_link(resp) + return resp + + class _DeleteMerchantCenterAccountLink(MerchantCenterAccountLinkServiceRestStub): + def __hash__(self): + return hash("DeleteMerchantCenterAccountLink") + + __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: merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete merchant center + account link method over HTTP. + + Args: + request (~.merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest): + The request object. Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/merchantCenterAccountLinks/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_merchant_center_account_link(request, metadata) + pb_request = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.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 _ListMerchantCenterAccountLinks(MerchantCenterAccountLinkServiceRestStub): + def __hash__(self): + return hash("ListMerchantCenterAccountLinks") + + __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: merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + r"""Call the list merchant center + account links method over HTTP. + + Args: + request (~.merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest): + The request object. Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + 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: + ~.merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse: + Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/merchantCenterAccountLinks', + }, + ] + request, metadata = self._interceptor.pre_list_merchant_center_account_links(request, metadata) + pb_request = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.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 = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + pb_resp = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_merchant_center_account_links(resp) + return resp + + @property + def create_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest], + 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._CreateMerchantCenterAccountLink(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_merchant_center_account_link(self) -> Callable[ + [merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest], + 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._DeleteMerchantCenterAccountLink(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_merchant_center_account_links(self) -> Callable[ + [merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest], + merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse]: + # 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._ListMerchantCenterAccountLinks(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(MerchantCenterAccountLinkServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(MerchantCenterAccountLinkServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'MerchantCenterAccountLinkServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/__init__.py new file mode 100644 index 00000000..2c368b92 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/__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 ModelServiceClient +from .async_client import ModelServiceAsyncClient + +__all__ = ( + 'ModelServiceClient', + 'ModelServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/async_client.py new file mode 100644 index 00000000..e611a4a9 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/async_client.py @@ -0,0 +1,1226 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.model_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model as gcr_model +from google.cloud.retail_v2alpha.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .client import ModelServiceClient + + +class ModelServiceAsyncClient: + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + _client: ModelServiceClient + + DEFAULT_ENDPOINT = ModelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ModelServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ModelServiceClient.catalog_path) + parse_catalog_path = staticmethod(ModelServiceClient.parse_catalog_path) + model_path = staticmethod(ModelServiceClient.model_path) + parse_model_path = staticmethod(ModelServiceClient.parse_model_path) + common_billing_account_path = staticmethod(ModelServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ModelServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ModelServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ModelServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ModelServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ModelServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ModelServiceClient.common_project_path) + parse_common_project_path = staticmethod(ModelServiceClient.parse_common_project_path) + common_location_path = staticmethod(ModelServiceClient.common_location_path) + parse_common_location_path = staticmethod(ModelServiceClient.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: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_info.__func__(ModelServiceAsyncClient, 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: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_file.__func__(ModelServiceAsyncClient, 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 ModelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ModelServiceClient).get_transport_class, type(ModelServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ModelServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service 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, ~.ModelServiceTransport]): 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 = ModelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_model(self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new model. + + .. 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 retail_v2alpha + + async def sample_create_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CreateModelRequest, dict]]): + The request object. Request for creating a model. + parent (:class:`str`): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (:class:`google.cloud.retail_v2alpha.types.Model`): + Required. The payload of the + [Model][google.cloud.retail.v2alpha.Model] to create. + + This corresponds to the ``model`` 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.retail_v2alpha.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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, model]) + 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 = model_service.CreateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # 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_model, + 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, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + async def get_model(self, + request: Optional[Union[model_service.GetModelRequest, 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]] = (), + ) -> model.Model: + r"""Gets a model. + + .. 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 retail_v2alpha + + async def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.GetModelRequest, dict]]): + The request object. Request for getting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.GetModelRequest(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_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def pause_model(self, + request: Optional[Union[model_service.PauseModelRequest, 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]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. 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 retail_v2alpha + + async def sample_pause_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.PauseModelRequest, dict]]): + The request object. Request for pausing training of a + model. + name (:class:`str`): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.PauseModelRequest(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.pause_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def resume_model(self, + request: Optional[Union[model_service.ResumeModelRequest, 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]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. 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 retail_v2alpha + + async def sample_resume_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ResumeModelRequest, dict]]): + The request object. Request for resuming training of a + model. + name (:class:`str`): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.ResumeModelRequest(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.resume_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_model(self, + request: Optional[Union[model_service.DeleteModelRequest, 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"""Deletes an existing model. + + .. 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 retail_v2alpha + + async def sample_delete_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.DeleteModelRequest, dict]]): + The request object. Request for deleting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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 = model_service.DeleteModelRequest(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_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_models(self, + request: Optional[Union[model_service.ListModelsRequest, 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.ListModelsAsyncPager: + r"""Lists all the models linked to this event store. + + .. 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 retail_v2alpha + + async def sample_list_models(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ListModelsRequest, dict]]): + The request object. Request for listing models associated + with a resource. + parent (:class:`str`): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2alpha.services.model_service.pagers.ListModelsAsyncPager: + Response to a ListModelRequest. + + 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 = model_service.ListModelsRequest(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_models, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListModelsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_model(self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = 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]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. 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 retail_v2alpha + + async def sample_update_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.UpdateModelRequest, dict]]): + The request object. Request for updating an existing + model. + model (:class:`google.cloud.retail_v2alpha.types.Model`): + Required. The body of the updated + [Model][google.cloud.retail.v2alpha.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + 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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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([model, 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 = model_service.UpdateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + 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_model, + 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(( + ("model.name", request.model.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def tune_model(self, + request: Optional[Union[model_service.TuneModelRequest, 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]] = (), + ) -> operation_async.AsyncOperation: + r"""Tunes an existing model. + + .. 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 retail_v2alpha + + async def sample_tune_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.TuneModelRequest, dict]]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (:class:`str`): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2alpha.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # 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 = model_service.TuneModelRequest(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.tune_model, + 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(( + ("name", request.name), + )), + ) + + # 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, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ModelServiceAsyncClient": + 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__ = ( + "ModelServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/client.py new file mode 100644 index 00000000..a790eeed --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/client.py @@ -0,0 +1,1442 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.model_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model as gcr_model +from google.cloud.retail_v2alpha.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ModelServiceGrpcTransport +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .transports.rest import ModelServiceRestTransport + + +class ModelServiceClientMeta(type): + """Metaclass for the ModelService 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[ModelServiceTransport]] + _transport_registry["grpc"] = ModelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ModelServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ModelServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ModelServiceTransport]: + """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 ModelServiceClient(metaclass=ModelServiceClientMeta): + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + @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 = "retail.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: + ModelServiceClient: 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: + ModelServiceClient: 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) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def model_path(project: str,location: str,catalog: str,model: str,) -> str: + """Returns a fully-qualified model string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format(project=project, location=location, catalog=catalog, model=model, ) + + @staticmethod + def parse_model_path(path: str) -> Dict[str,str]: + """Parses a model path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/models/(?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, ModelServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service 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, ModelServiceTransport]): 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, ModelServiceTransport): + # transport is a ModelServiceTransport 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_model(self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a new model. + + .. 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 retail_v2alpha + + def sample_create_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CreateModelRequest, dict]): + The request object. Request for creating a model. + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (google.cloud.retail_v2alpha.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2alpha.Model] to create. + + This corresponds to the ``model`` 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.retail_v2alpha.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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, model]) + 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 model_service.CreateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.CreateModelRequest): + request = model_service.CreateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_model] + + # 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, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + def get_model(self, + request: Optional[Union[model_service.GetModelRequest, 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]] = (), + ) -> model.Model: + r"""Gets a model. + + .. 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 retail_v2alpha + + def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetModelRequest, dict]): + The request object. Request for getting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.GetModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.GetModelRequest): + request = model_service.GetModelRequest(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_model] + + # 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 pause_model(self, + request: Optional[Union[model_service.PauseModelRequest, 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]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. 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 retail_v2alpha + + def sample_pause_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.PauseModelRequest, dict]): + The request object. Request for pausing training of a + model. + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.PauseModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.PauseModelRequest): + request = model_service.PauseModelRequest(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.pause_model] + + # 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 resume_model(self, + request: Optional[Union[model_service.ResumeModelRequest, 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]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. 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 retail_v2alpha + + def sample_resume_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ResumeModelRequest, dict]): + The request object. Request for resuming training of a + model. + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.ResumeModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ResumeModelRequest): + request = model_service.ResumeModelRequest(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.resume_model] + + # 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 delete_model(self, + request: Optional[Union[model_service.DeleteModelRequest, 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"""Deletes an existing model. + + .. 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 retail_v2alpha + + def sample_delete_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + Args: + request (Union[google.cloud.retail_v2alpha.types.DeleteModelRequest, dict]): + The request object. Request for deleting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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 model_service.DeleteModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.DeleteModelRequest): + request = model_service.DeleteModelRequest(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_model] + + # 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_models(self, + request: Optional[Union[model_service.ListModelsRequest, 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.ListModelsPager: + r"""Lists all the models linked to this event store. + + .. 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 retail_v2alpha + + def sample_list_models(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ListModelsRequest, dict]): + The request object. Request for listing models associated + with a resource. + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2alpha.services.model_service.pagers.ListModelsPager: + Response to a ListModelRequest. + + 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 model_service.ListModelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ListModelsRequest): + request = model_service.ListModelsRequest(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_models] + + # 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.ListModelsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_model(self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = 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]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. 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 retail_v2alpha + + def sample_update_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.UpdateModelRequest, dict]): + The request object. Request for updating an existing + model. + model (google.cloud.retail_v2alpha.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2alpha.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + 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.retail_v2alpha.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + # 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([model, 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 model_service.UpdateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.UpdateModelRequest): + request = model_service.UpdateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + 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_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("model.name", request.model.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def tune_model(self, + request: Optional[Union[model_service.TuneModelRequest, 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]] = (), + ) -> operation.Operation: + r"""Tunes an existing model. + + .. 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 retail_v2alpha + + def sample_tune_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.TuneModelRequest, dict]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (str): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2alpha.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # 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 model_service.TuneModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.TuneModelRequest): + request = model_service.TuneModelRequest(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.tune_model] + + # 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, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ModelServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ModelServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/pagers.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/pagers.py new file mode 100644 index 00000000..31900bd6 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model_service + + +class ListModelsPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListModelsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListModelsResponse` + 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[..., model_service.ListModelsResponse], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + 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.retail_v2alpha.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListModelsResponse): + 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 = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[model_service.ListModelsResponse]: + 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[model.Model]: + for page in self.pages: + yield from page.models + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListModelsAsyncPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListModelsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListModelsResponse` + 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[model_service.ListModelsResponse]], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + 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.retail_v2alpha.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListModelsResponse): + 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 = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[model_service.ListModelsResponse]: + 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[model.Model]: + async def async_generator(): + async for page in self.pages: + for response in page.models: + 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/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/__init__.py new file mode 100644 index 00000000..c51cadf4 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/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 ModelServiceTransport +from .grpc import ModelServiceGrpcTransport +from .grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .rest import ModelServiceRestTransport +from .rest import ModelServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ModelServiceTransport]] +_transport_registry['grpc'] = ModelServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ModelServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ModelServiceRestTransport + +__all__ = ( + 'ModelServiceTransport', + 'ModelServiceGrpcTransport', + 'ModelServiceGrpcAsyncIOTransport', + 'ModelServiceRestTransport', + 'ModelServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/base.py new file mode 100644 index 00000000..6fec93e5 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/base.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model as gcr_model +from google.cloud.retail_v2alpha.types import model_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 ModelServiceTransport(abc.ABC): + """Abstract transport class for ModelService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_model: gapic_v1.method.wrap_method( + self.create_model, + default_timeout=None, + client_info=client_info, + ), + self.get_model: gapic_v1.method.wrap_method( + self.get_model, + default_timeout=None, + client_info=client_info, + ), + self.pause_model: gapic_v1.method.wrap_method( + self.pause_model, + default_timeout=None, + client_info=client_info, + ), + self.resume_model: gapic_v1.method.wrap_method( + self.resume_model, + default_timeout=None, + client_info=client_info, + ), + self.delete_model: gapic_v1.method.wrap_method( + self.delete_model, + default_timeout=None, + client_info=client_info, + ), + self.list_models: gapic_v1.method.wrap_method( + self.list_models, + default_timeout=None, + client_info=client_info, + ), + self.update_model: gapic_v1.method.wrap_method( + self.update_model, + default_timeout=None, + client_info=client_info, + ), + self.tune_model: gapic_v1.method.wrap_method( + self.tune_model, + 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_model(self) -> Callable[ + [model_service.CreateModelRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + Union[ + model_service.ListModelsResponse, + Awaitable[model_service.ListModelsResponse] + ]]: + raise NotImplementedError() + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + Union[ + gcr_model.Model, + Awaitable[gcr_model.Model] + ]]: + raise NotImplementedError() + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ModelServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py new file mode 100644 index 00000000..750e2c4b --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc.py @@ -0,0 +1,518 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model as gcr_model +from google.cloud.retail_v2alpha.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ModelServiceTransport, DEFAULT_CLIENT_INFO + + +class ModelServiceGrpcTransport(ModelServiceTransport): + """gRPC backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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 = 'retail.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_model(self) -> Callable[ + [model_service.CreateModelRequest], + operations_pb2.Operation]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + ~.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 'create_model' not in self._stubs: + self._stubs['create_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/CreateModel', + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_model'] + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + model.Model]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + ~.Model]: + 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_model' not in self._stubs: + self._stubs['get_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/GetModel', + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['get_model'] + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + model.Model]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + ~.Model]: + 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 'pause_model' not in self._stubs: + self._stubs['pause_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/PauseModel', + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['pause_model'] + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + model.Model]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + ~.Model]: + 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 'resume_model' not in self._stubs: + self._stubs['resume_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/ResumeModel', + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['resume_model'] + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + ~.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_model' not in self._stubs: + self._stubs['delete_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/DeleteModel', + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_model'] + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + model_service.ListModelsResponse]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + ~.ListModelsResponse]: + 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_models' not in self._stubs: + self._stubs['list_models'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/ListModels', + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs['list_models'] + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + gcr_model.Model]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + ~.Model]: + 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_model' not in self._stubs: + self._stubs['update_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/UpdateModel', + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs['update_model'] + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + operations_pb2.Operation]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + ~.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 'tune_model' not in self._stubs: + self._stubs['tune_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/TuneModel', + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['tune_model'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ModelServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..ae961b17 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/grpc_asyncio.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model as gcr_model +from google.cloud.retail_v2alpha.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ModelServiceGrpcTransport + + +class ModelServiceGrpcAsyncIOTransport(ModelServiceTransport): + """gRPC AsyncIO backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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 = 'retail.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_model(self) -> Callable[ + [model_service.CreateModelRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + 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 'create_model' not in self._stubs: + self._stubs['create_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/CreateModel', + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_model'] + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + Awaitable[~.Model]]: + 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_model' not in self._stubs: + self._stubs['get_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/GetModel', + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['get_model'] + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + Awaitable[~.Model]]: + 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 'pause_model' not in self._stubs: + self._stubs['pause_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/PauseModel', + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['pause_model'] + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + Awaitable[~.Model]]: + 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 'resume_model' not in self._stubs: + self._stubs['resume_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/ResumeModel', + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['resume_model'] + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + 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_model' not in self._stubs: + self._stubs['delete_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/DeleteModel', + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_model'] + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + Awaitable[model_service.ListModelsResponse]]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + Awaitable[~.ListModelsResponse]]: + 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_models' not in self._stubs: + self._stubs['list_models'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/ListModels', + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs['list_models'] + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + Awaitable[gcr_model.Model]]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + Awaitable[~.Model]]: + 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_model' not in self._stubs: + self._stubs['update_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/UpdateModel', + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs['update_model'] + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + 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 'tune_model' not in self._stubs: + self._stubs['tune_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ModelService/TuneModel', + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['tune_model'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ModelServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/rest.py new file mode 100644 index 00000000..6cb82fd9 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/model_service/transports/rest.py @@ -0,0 +1,1390 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model as gcr_model +from google.cloud.retail_v2alpha.types import model_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ModelServiceTransport, 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 ModelServiceRestInterceptor: + """Interceptor for ModelService. + + 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 ModelServiceRestTransport. + + .. code-block:: python + class MyCustomModelServiceInterceptor(ModelServiceRestInterceptor): + def pre_create_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_models(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_models(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_pause_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_pause_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_resume_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_resume_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_tune_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_tune_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_model(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ModelServiceRestTransport(interceptor=MyCustomModelServiceInterceptor()) + client = ModelServiceClient(transport=transport) + + + """ + def pre_create_model(self, request: model_service.CreateModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.CreateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_create_model(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for create_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_delete_model(self, request: model_service.DeleteModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.DeleteModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def pre_get_model(self, request: model_service.GetModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.GetModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for get_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_models(self, request: model_service.ListModelsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.ListModelsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_models + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_models(self, response: model_service.ListModelsResponse) -> model_service.ListModelsResponse: + """Post-rpc interceptor for list_models + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_pause_model(self, request: model_service.PauseModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.PauseModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for pause_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_pause_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for pause_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_resume_model(self, request: model_service.ResumeModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.ResumeModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for resume_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_resume_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for resume_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_tune_model(self, request: model_service.TuneModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.TuneModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for tune_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_tune_model(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for tune_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_update_model(self, request: model_service.UpdateModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.UpdateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_update_model(self, response: gcr_model.Model) -> gcr_model.Model: + """Post-rpc interceptor for update_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ModelServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ModelServiceRestInterceptor + + +class ModelServiceRestTransport(ModelServiceTransport): + """REST backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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[ModelServiceRestInterceptor] = 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 ModelServiceRestInterceptor() + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/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="v2alpha") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CreateModel(ModelServiceRestStub): + def __hash__(self): + return hash("CreateModel") + + __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: model_service.CreateModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the create model method over HTTP. + + Args: + request (~.model_service.CreateModelRequest): + The request object. Request for creating a model. + 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/models', + 'body': 'model', + }, + ] + request, metadata = self._interceptor.pre_create_model(request, metadata) + pb_request = model_service.CreateModelRequest.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_create_model(resp) + return resp + + class _DeleteModel(ModelServiceRestStub): + def __hash__(self): + return hash("DeleteModel") + + __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: model_service.DeleteModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete model method over HTTP. + + Args: + request (~.model_service.DeleteModelRequest): + The request object. Request for deleting a model. + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_model(request, metadata) + pb_request = model_service.DeleteModelRequest.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 _GetModel(ModelServiceRestStub): + def __hash__(self): + return hash("GetModel") + + __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: model_service.GetModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the get model method over HTTP. + + Args: + request (~.model_service.GetModelRequest): + The request object. Request for getting a model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}', + }, + ] + request, metadata = self._interceptor.pre_get_model(request, metadata) + pb_request = model_service.GetModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_model(resp) + return resp + + class _ListModels(ModelServiceRestStub): + def __hash__(self): + return hash("ListModels") + + __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: model_service.ListModelsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model_service.ListModelsResponse: + r"""Call the list models method over HTTP. + + Args: + request (~.model_service.ListModelsRequest): + The request object. Request for listing models associated + with a resource. + 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: + ~.model_service.ListModelsResponse: + Response to a ListModelRequest. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/models', + }, + ] + request, metadata = self._interceptor.pre_list_models(request, metadata) + pb_request = model_service.ListModelsRequest.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 = model_service.ListModelsResponse() + pb_resp = model_service.ListModelsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_models(resp) + return resp + + class _PauseModel(ModelServiceRestStub): + def __hash__(self): + return hash("PauseModel") + + __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: model_service.PauseModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the pause model method over HTTP. + + Args: + request (~.model_service.PauseModelRequest): + The request object. Request for pausing training of a + model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}:pause', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_pause_model(request, metadata) + pb_request = model_service.PauseModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_pause_model(resp) + return resp + + class _ResumeModel(ModelServiceRestStub): + def __hash__(self): + return hash("ResumeModel") + + __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: model_service.ResumeModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the resume model method over HTTP. + + Args: + request (~.model_service.ResumeModelRequest): + The request object. Request for resuming training of a + model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}:resume', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_resume_model(request, metadata) + pb_request = model_service.ResumeModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_resume_model(resp) + return resp + + class _TuneModel(ModelServiceRestStub): + def __hash__(self): + return hash("TuneModel") + + __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: model_service.TuneModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the tune model method over HTTP. + + Args: + request (~.model_service.TuneModelRequest): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}:tune', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_tune_model(request, metadata) + pb_request = model_service.TuneModelRequest.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_tune_model(resp) + return resp + + class _UpdateModel(ModelServiceRestStub): + def __hash__(self): + return hash("UpdateModel") + + __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: model_service.UpdateModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_model.Model: + r"""Call the update model method over HTTP. + + Args: + request (~.model_service.UpdateModelRequest): + The request object. Request for updating an existing + model. + 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: + ~.gcr_model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2alpha/{model.name=projects/*/locations/*/catalogs/*/models/*}', + 'body': 'model', + }, + ] + request, metadata = self._interceptor.pre_update_model(request, metadata) + pb_request = model_service.UpdateModelRequest.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 = gcr_model.Model() + pb_resp = gcr_model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_model(resp) + return resp + + @property + def create_model(self) -> Callable[ + [model_service.CreateModelRequest], + 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._CreateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + 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._DeleteModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + model.Model]: + # 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._GetModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + model_service.ListModelsResponse]: + # 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._ListModels(self._session, self._host, self._interceptor) # type: ignore + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + model.Model]: + # 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._PauseModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + model.Model]: + # 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._ResumeModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + 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._TuneModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + gcr_model.Model]: + # 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._UpdateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ModelServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ModelServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ModelServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/__init__.py new file mode 100644 index 00000000..905b8c43 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/__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 PredictionServiceClient +from .async_client import PredictionServiceAsyncClient + +__all__ = ( + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/async_client.py new file mode 100644 index 00000000..42391e36 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/async_client.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .client import PredictionServiceClient + + +class PredictionServiceAsyncClient: + """Service for making recommendation prediction.""" + + _client: PredictionServiceClient + + DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(PredictionServiceClient.product_path) + parse_product_path = staticmethod(PredictionServiceClient.parse_product_path) + common_billing_account_path = staticmethod(PredictionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(PredictionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(PredictionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(PredictionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(PredictionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(PredictionServiceClient.common_project_path) + parse_common_project_path = staticmethod(PredictionServiceClient.parse_common_project_path) + common_location_path = staticmethod(PredictionServiceClient.common_location_path) + parse_common_location_path = staticmethod(PredictionServiceClient.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: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_info.__func__(PredictionServiceAsyncClient, 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: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_file.__func__(PredictionServiceAsyncClient, 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 PredictionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service 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, ~.PredictionServiceTransport]): 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 = PredictionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def predict(self, + request: Optional[Union[prediction_service.PredictRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + .. 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 retail_v2alpha + + async def sample_predict(): + # Create a client + client = retail_v2alpha.PredictionServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = await client.predict(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.PredictRequest, dict]]): + The request object. Request message for Predict 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: + google.cloud.retail_v2alpha.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.predict, + 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(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "PredictionServiceAsyncClient": + 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__ = ( + "PredictionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/client.py new file mode 100644 index 00000000..0c9d03a1 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/client.py @@ -0,0 +1,592 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import PredictionServiceGrpcTransport +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .transports.rest import PredictionServiceRestTransport + + +class PredictionServiceClientMeta(type): + """Metaclass for the PredictionService 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[PredictionServiceTransport]] + _transport_registry["grpc"] = PredictionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = PredictionServiceGrpcAsyncIOTransport + _transport_registry["rest"] = PredictionServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[PredictionServiceTransport]: + """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 PredictionServiceClient(metaclass=PredictionServiceClientMeta): + """Service for making recommendation prediction.""" + + @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 = "retail.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: + PredictionServiceClient: 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: + PredictionServiceClient: 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) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, PredictionServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service 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, PredictionServiceTransport]): 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, PredictionServiceTransport): + # transport is a PredictionServiceTransport 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 predict(self, + request: Optional[Union[prediction_service.PredictRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + .. 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 retail_v2alpha + + def sample_predict(): + # Create a client + client = retail_v2alpha.PredictionServiceClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = client.predict(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.PredictRequest, dict]): + The request object. Request message for Predict 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: + google.cloud.retail_v2alpha.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a prediction_service.PredictRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, prediction_service.PredictRequest): + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.predict] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "PredictionServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "PredictionServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/__init__.py new file mode 100644 index 00000000..d8c81688 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/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 PredictionServiceTransport +from .grpc import PredictionServiceGrpcTransport +from .grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .rest import PredictionServiceRestTransport +from .rest import PredictionServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[PredictionServiceTransport]] +_transport_registry['grpc'] = PredictionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = PredictionServiceGrpcAsyncIOTransport +_transport_registry['rest'] = PredictionServiceRestTransport + +__all__ = ( + 'PredictionServiceTransport', + 'PredictionServiceGrpcTransport', + 'PredictionServiceGrpcAsyncIOTransport', + 'PredictionServiceRestTransport', + 'PredictionServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/base.py new file mode 100644 index 00000000..3355f6b9 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/base.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class PredictionServiceTransport(abc.ABC): + """Abstract transport class for PredictionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.predict: gapic_v1.method.wrap_method( + self.predict, + 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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + Union[ + prediction_service.PredictResponse, + Awaitable[prediction_service.PredictResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'PredictionServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc.py new file mode 100644 index 00000000..50ab6bbc --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc.py @@ -0,0 +1,302 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO + + +class PredictionServiceGrpcTransport(PredictionServiceTransport): + """gRPC backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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 = 'retail.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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + prediction_service.PredictResponse]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + ~.PredictResponse]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'PredictionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..e9c5ea15 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/grpc_asyncio.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import PredictionServiceGrpcTransport + + +class PredictionServiceGrpcAsyncIOTransport(PredictionServiceTransport): + """gRPC AsyncIO backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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 = 'retail.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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + Awaitable[prediction_service.PredictResponse]]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + Awaitable[~.PredictResponse]]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'PredictionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/rest.py new file mode 100644 index 00000000..4801dfdb --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/prediction_service/transports/rest.py @@ -0,0 +1,499 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import PredictionServiceTransport, 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 PredictionServiceRestInterceptor: + """Interceptor for PredictionService. + + 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 PredictionServiceRestTransport. + + .. code-block:: python + class MyCustomPredictionServiceInterceptor(PredictionServiceRestInterceptor): + def pre_predict(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_predict(self, response): + logging.log(f"Received response: {response}") + return response + + transport = PredictionServiceRestTransport(interceptor=MyCustomPredictionServiceInterceptor()) + client = PredictionServiceClient(transport=transport) + + + """ + def pre_predict(self, request: prediction_service.PredictRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[prediction_service.PredictRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for predict + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_predict(self, response: prediction_service.PredictResponse) -> prediction_service.PredictResponse: + """Post-rpc interceptor for predict + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class PredictionServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: PredictionServiceRestInterceptor + + +class PredictionServiceRestTransport(PredictionServiceTransport): + """REST backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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[PredictionServiceRestInterceptor] = 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 PredictionServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _Predict(PredictionServiceRestStub): + def __hash__(self): + return hash("Predict") + + __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: prediction_service.PredictRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> prediction_service.PredictResponse: + r"""Call the predict method over HTTP. + + Args: + request (~.prediction_service.PredictRequest): + The request object. Request message for Predict 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: + ~.prediction_service.PredictResponse: + Response message for predict method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{placement=projects/*/locations/*/catalogs/*/placements/*}:predict', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v2alpha/{placement=projects/*/locations/*/catalogs/*/servingConfigs/*}:predict', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_predict(request, metadata) + pb_request = prediction_service.PredictRequest.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 = prediction_service.PredictResponse() + pb_resp = prediction_service.PredictResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_predict(resp) + return resp + + @property + def predict(self) -> Callable[ + [prediction_service.PredictRequest], + prediction_service.PredictResponse]: + # 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._Predict(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(PredictionServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(PredictionServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'PredictionServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/__init__.py new file mode 100644 index 00000000..fee01226 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/__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 ProductServiceClient +from .async_client import ProductServiceAsyncClient + +__all__ = ( + 'ProductServiceClient', + 'ProductServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/async_client.py new file mode 100644 index 00000000..a1c6f6f2 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/async_client.py @@ -0,0 +1,2060 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.product_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.cloud.retail_v2alpha.types import product_service +from google.cloud.retail_v2alpha.types import promotion +from google.cloud.retail_v2alpha.types import purge_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .client import ProductServiceClient + + +class ProductServiceAsyncClient: + """Service for ingesting [Product][google.cloud.retail.v2alpha.Product] + information of the customer's website. + """ + + _client: ProductServiceClient + + DEFAULT_ENDPOINT = ProductServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(ProductServiceClient.branch_path) + parse_branch_path = staticmethod(ProductServiceClient.parse_branch_path) + product_path = staticmethod(ProductServiceClient.product_path) + parse_product_path = staticmethod(ProductServiceClient.parse_product_path) + common_billing_account_path = staticmethod(ProductServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ProductServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ProductServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ProductServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ProductServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ProductServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ProductServiceClient.common_project_path) + parse_common_project_path = staticmethod(ProductServiceClient.parse_common_project_path) + common_location_path = staticmethod(ProductServiceClient.common_location_path) + parse_common_location_path = staticmethod(ProductServiceClient.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: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_info.__func__(ProductServiceAsyncClient, 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: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_file.__func__(ProductServiceAsyncClient, 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 ProductServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ProductServiceClient).get_transport_class, type(ProductServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ProductServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product service 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, ~.ProductServiceTransport]): 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 = ProductServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_product(self, + request: Optional[Union[product_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + async def sample_create_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CreateProductRequest, dict]]): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + method. + parent (:class:`str`): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`google.cloud.retail_v2alpha.types.Product`): + Required. The + [Product][google.cloud.retail.v2alpha.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`): + Required. The ID to use for the + [Product][google.cloud.retail.v2alpha.Product], which + will become the final component of the + [Product.name][google.cloud.retail.v2alpha.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This field must be unique among all + [Product][google.cloud.retail.v2alpha.Product]s with the + same + [parent][google.cloud.retail.v2alpha.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + 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.retail_v2alpha.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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, + ) + + # Done; return the response. + return response + + async def get_product(self, + request: Optional[Union[product_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.Product: + r"""Gets a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + async def sample_get_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.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.retail_v2alpha.types.GetProductRequest, dict]]): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + method. + name (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the requested + [Product][google.cloud.retail.v2alpha.Product] does not + exist, a NOT_FOUND error is returned. + + 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.retail_v2alpha.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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(( + ("name", request.name), + )), + ) + + # 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_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"""Gets a list of [Product][google.cloud.retail.v2alpha.Product]s. + + .. 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 retail_v2alpha + + async def sample_list_products(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.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.retail_v2alpha.types.ListProductsRequest, dict]]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + method. + parent (:class:`str`): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2alpha.Product]s under + this branch, regardless of whether or not this branch + exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2alpha.services.product_service.pagers.ListProductsAsyncPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.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_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_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, + ) + + # 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 update_product(self, + request: Optional[Union[product_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + async def sample_update_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.UpdateProductRequest( + product=product, + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.UpdateProductRequest, dict]]): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + method. + product (:class:`google.cloud.retail_v2alpha.types.Product`): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2alpha.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + 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`): + Indicates which fields in the provided + [Product][google.cloud.retail.v2alpha.Product] to + update. The immutable and output only fields are NOT + supported. If not set, all supported fields (the fields + that are neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask + path as "attributes.${key_name}". If a key name is + present in the mask but not in the patching product from + the request, this key will be deleted after the update. + + 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.retail_v2alpha.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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(( + ("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_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"""Deletes a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + async def sample_delete_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.DeleteProductRequest, dict]]): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2alpha.ProductService.DeleteProduct] + method. + name (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2alpha.Product] to + delete can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2alpha.Product] member + nor a + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product] with more + than one + [variants][google.cloud.retail.v2alpha.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2alpha.Product] will be + deleted. + + 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_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_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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def purge_products(self, + request: Optional[Union[purge_config.PurgeProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Permanently deletes all selected + [Product][google.cloud.retail.v2alpha.Product]s under a branch. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed offline. Depending on the + number of [Product][google.cloud.retail.v2alpha.Product]s, this + operation could take hours to complete. Before the operation + completes, some [Product][google.cloud.retail.v2alpha.Product]s + may still be returned by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Depending on the number of + [Product][google.cloud.retail.v2alpha.Product]s, this operation + could take hours to complete. To get a sample of + [Product][google.cloud.retail.v2alpha.Product]s that would be + deleted, set + [PurgeProductsRequest.force][google.cloud.retail.v2alpha.PurgeProductsRequest.force] + to false. + + .. 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 retail_v2alpha + + async def sample_purge_products(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeProductsRequest( + parent="parent_value", + filter="filter_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.retail_v2alpha.types.PurgeProductsRequest, dict]]): + The request object. Request message for 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: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.PurgeProductsResponse` Response of the PurgeProductsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + request = purge_config.PurgeProductsRequest(request) + + # 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, + purge_config.PurgeProductsResponse, + metadata_type=purge_config.PurgeProductsMetadata, + ) + + # Done; return the response. + return response + + async def import_products(self, + request: Optional[Union[import_config.ImportProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2alpha.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2alpha.Product]s to be + successfully updated. + + .. 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 retail_v2alpha + + async def sample_import_products(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2alpha.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ImportProductsRequest, dict]]): + The request object. Request message for Import methods. + 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.retail_v2alpha.types.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2alpha.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportProductsRequest(request) + + # 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_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.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, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def set_inventory(self, + request: Optional[Union[product_service.SetInventoryRequest, dict]] = None, + *, + inventory: Optional[product.Product] = None, + set_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]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2alpha.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2alpha.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2alpha.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + .. 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 retail_v2alpha + + async def sample_set_inventory(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + inventory = retail_v2alpha.Product() + inventory.title = "title_value" + + request = retail_v2alpha.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.SetInventoryRequest, dict]]): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + method. + inventory (:class:`google.cloud.retail_v2alpha.types.Product`): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + - [Product.availability][google.cloud.retail.v2alpha.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2alpha.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2alpha.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is + returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2alpha.Product] named in + [Product.name][google.cloud.retail.v2alpha.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2alpha.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + - [Product.availability][google.cloud.retail.v2alpha.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2alpha.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + should be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + set_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2alpha.Product] to + update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_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.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + method. + + """ + # 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([inventory, set_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_service.SetInventoryRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_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.set_inventory, + 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(( + ("inventory.name", request.inventory.name), + )), + ) + + # 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_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + async def add_fulfillment_places(self, + request: Optional[Union[product_service.AddFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + async def sample_add_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.AddFulfillmentPlacesRequest, dict]]): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2alpha.types.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.AddFulfillmentPlacesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places, + 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(( + ("product", request.product), + )), + ) + + # 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_service.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def remove_fulfillment_places(self, + request: Optional[Union[product_service.RemoveFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + async def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.RemoveFulfillmentPlacesRequest, dict]]): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2alpha.types.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.RemoveFulfillmentPlacesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places, + 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(( + ("product", request.product), + )), + ) + + # 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_service.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def add_local_inventories(self, + request: Optional[Union[product_service.AddLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Updates local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + async def sample_add_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.AddLocalInventoriesRequest, dict]]): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2alpha.types.AddLocalInventoriesResponse` Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method. + + """ + # 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]) + 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_service.AddLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories, + 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(( + ("product", request.product), + )), + ) + + # 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_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + async def remove_local_inventories(self, + request: Optional[Union[product_service.RemoveLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Remove local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + async def sample_remove_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.RemoveLocalInventoriesRequest, dict]]): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2alpha.types.RemoveLocalInventoriesResponse` Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method. + + """ + # 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]) + 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_service.RemoveLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories, + 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(( + ("product", request.product), + )), + ) + + # 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_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductServiceAsyncClient": + 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__ = ( + "ProductServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/client.py new file mode 100644 index 00000000..daffd2d2 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/client.py @@ -0,0 +1,2271 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.product_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.cloud.retail_v2alpha.types import product_service +from google.cloud.retail_v2alpha.types import promotion +from google.cloud.retail_v2alpha.types import purge_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductServiceGrpcTransport +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .transports.rest import ProductServiceRestTransport + + +class ProductServiceClientMeta(type): + """Metaclass for the ProductService 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[ProductServiceTransport]] + _transport_registry["grpc"] = ProductServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ProductServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ProductServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ProductServiceTransport]: + """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 ProductServiceClient(metaclass=ProductServiceClientMeta): + """Service for ingesting [Product][google.cloud.retail.v2alpha.Product] + information of the customer's website. + """ + + @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 = "retail.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: + ProductServiceClient: 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: + ProductServiceClient: 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) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, ProductServiceTransport]] = 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 service 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, ProductServiceTransport]): 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, ProductServiceTransport): + # transport is a ProductServiceTransport 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(self, + request: Optional[Union[product_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + def sample_create_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CreateProductRequest, dict]): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + method. + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (google.cloud.retail_v2alpha.types.Product): + Required. The + [Product][google.cloud.retail.v2alpha.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): + Required. The ID to use for the + [Product][google.cloud.retail.v2alpha.Product], which + will become the final component of the + [Product.name][google.cloud.retail.v2alpha.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This field must be unique among all + [Product][google.cloud.retail.v2alpha.Product]s with the + same + [parent][google.cloud.retail.v2alpha.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + 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.retail_v2alpha.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.CreateProductRequest): + request = product_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 get_product(self, + request: Optional[Union[product_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.Product: + r"""Gets a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + def sample_get_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetProductRequest, dict]): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + method. + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the requested + [Product][google.cloud.retail.v2alpha.Product] does not + exist, a NOT_FOUND error is returned. + + 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.retail_v2alpha.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.GetProductRequest): + request = product_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 list_products(self, + request: Optional[Union[product_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"""Gets a list of [Product][google.cloud.retail.v2alpha.Product]s. + + .. 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 retail_v2alpha + + def sample_list_products(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.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.retail_v2alpha.types.ListProductsRequest, dict]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + method. + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2alpha.Product]s under + this branch, regardless of whether or not this branch + exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2alpha.services.product_service.pagers.ListProductsPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.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_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_service.ListProductsRequest): + request = product_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 update_product(self, + request: Optional[Union[product_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + def sample_update_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.UpdateProductRequest( + product=product, + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.UpdateProductRequest, dict]): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + method. + product (google.cloud.retail_v2alpha.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2alpha.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + 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): + Indicates which fields in the provided + [Product][google.cloud.retail.v2alpha.Product] to + update. The immutable and output only fields are NOT + supported. If not set, all supported fields (the fields + that are neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask + path as "attributes.${key_name}". If a key name is + present in the mask but not in the patching product from + the request, this key will be deleted after the update. + + 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.retail_v2alpha.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.UpdateProductRequest): + request = product_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_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"""Deletes a [Product][google.cloud.retail.v2alpha.Product]. + + .. 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 retail_v2alpha + + def sample_delete_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + Args: + request (Union[google.cloud.retail_v2alpha.types.DeleteProductRequest, dict]): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2alpha.ProductService.DeleteProduct] + method. + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2alpha.Product] to + delete can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2alpha.Product] member + nor a + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product] with more + than one + [variants][google.cloud.retail.v2alpha.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2alpha.Product] will be + deleted. + + 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_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_service.DeleteProductRequest): + request = product_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 purge_products(self, + request: Optional[Union[purge_config.PurgeProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Permanently deletes all selected + [Product][google.cloud.retail.v2alpha.Product]s under a branch. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed offline. Depending on the + number of [Product][google.cloud.retail.v2alpha.Product]s, this + operation could take hours to complete. Before the operation + completes, some [Product][google.cloud.retail.v2alpha.Product]s + may still be returned by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Depending on the number of + [Product][google.cloud.retail.v2alpha.Product]s, this operation + could take hours to complete. To get a sample of + [Product][google.cloud.retail.v2alpha.Product]s that would be + deleted, set + [PurgeProductsRequest.force][google.cloud.retail.v2alpha.PurgeProductsRequest.force] + to false. + + .. 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 retail_v2alpha + + def sample_purge_products(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeProductsRequest( + parent="parent_value", + filter="filter_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.retail_v2alpha.types.PurgeProductsRequest, dict]): + The request object. Request message for 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: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.PurgeProductsResponse` Response of the PurgeProductsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a purge_config.PurgeProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, purge_config.PurgeProductsRequest): + request = purge_config.PurgeProductsRequest(request) + + # 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, + purge_config.PurgeProductsResponse, + metadata_type=purge_config.PurgeProductsMetadata, + ) + + # Done; return the response. + return response + + def import_products(self, + request: Optional[Union[import_config.ImportProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2alpha.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2alpha.Product]s to be + successfully updated. + + .. 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 retail_v2alpha + + def sample_import_products(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2alpha.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ImportProductsRequest, dict]): + The request object. Request message for Import methods. + 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.retail_v2alpha.types.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2alpha.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportProductsRequest): + request = import_config.ImportProductsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_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, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def set_inventory(self, + request: Optional[Union[product_service.SetInventoryRequest, dict]] = None, + *, + inventory: Optional[product.Product] = None, + set_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]] = (), + ) -> operation.Operation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2alpha.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2alpha.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2alpha.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + .. 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 retail_v2alpha + + def sample_set_inventory(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + inventory = retail_v2alpha.Product() + inventory.title = "title_value" + + request = retail_v2alpha.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.SetInventoryRequest, dict]): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + method. + inventory (google.cloud.retail_v2alpha.types.Product): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + - [Product.availability][google.cloud.retail.v2alpha.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2alpha.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2alpha.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is + returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2alpha.Product] named in + [Product.name][google.cloud.retail.v2alpha.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2alpha.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + - [Product.availability][google.cloud.retail.v2alpha.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2alpha.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + should be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + set_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2alpha.Product] to + update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_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.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + method. + + """ + # 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([inventory, set_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_service.SetInventoryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.SetInventoryRequest): + request = product_service.SetInventoryRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_inventory] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("inventory.name", request.inventory.name), + )), + ) + + # 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_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + def add_fulfillment_places(self, + request: Optional[Union[product_service.AddFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + def sample_add_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.AddFulfillmentPlacesRequest, dict]): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.AddFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddFulfillmentPlacesRequest): + request = product_service.AddFulfillmentPlacesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def remove_fulfillment_places(self, + request: Optional[Union[product_service.RemoveFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.RemoveFulfillmentPlacesRequest, dict]): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.RemoveFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveFulfillmentPlacesRequest): + request = product_service.RemoveFulfillmentPlacesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def add_local_inventories(self, + request: Optional[Union[product_service.AddLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Updates local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + def sample_add_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.AddLocalInventoriesRequest, dict]): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.AddLocalInventoriesResponse` Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method. + + """ + # 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]) + 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_service.AddLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddLocalInventoriesRequest): + request = product_service.AddLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + def remove_local_inventories(self, + request: Optional[Union[product_service.RemoveLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Remove local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2alpha + + def sample_remove_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.RemoveLocalInventoriesRequest, dict]): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.RemoveLocalInventoriesResponse` Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method. + + """ + # 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]) + 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_service.RemoveLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveLocalInventoriesRequest): + request = product_service.RemoveLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/pagers.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/pagers.py new file mode 100644 index 00000000..b75b7354 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product_service + + +class ListProductsPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.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.retail_v2alpha.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_service.ListProductsResponse], + request: product_service.ListProductsRequest, + response: product_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.retail_v2alpha.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.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_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_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.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.retail_v2alpha.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.retail_v2alpha.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_service.ListProductsResponse]], + request: product_service.ListProductsRequest, + response: product_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.retail_v2alpha.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.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_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_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.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/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/__init__.py new file mode 100644 index 00000000..b9528228 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/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 ProductServiceTransport +from .grpc import ProductServiceGrpcTransport +from .grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .rest import ProductServiceRestTransport +from .rest import ProductServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ProductServiceTransport]] +_transport_registry['grpc'] = ProductServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ProductServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ProductServiceRestTransport + +__all__ = ( + 'ProductServiceTransport', + 'ProductServiceGrpcTransport', + 'ProductServiceGrpcAsyncIOTransport', + 'ProductServiceRestTransport', + 'ProductServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/base.py new file mode 100644 index 00000000..db7b43b9 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/base.py @@ -0,0 +1,340 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.cloud.retail_v2alpha.types import product_service +from google.cloud.retail_v2alpha.types import purge_config +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 ProductServiceTransport(abc.ABC): + """Abstract transport class for ProductService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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: gapic_v1.method.wrap_method( + self.create_product, + default_timeout=None, + client_info=client_info, + ), + self.get_product: gapic_v1.method.wrap_method( + self.get_product, + default_timeout=None, + client_info=client_info, + ), + self.list_products: gapic_v1.method.wrap_method( + self.list_products, + default_timeout=None, + client_info=client_info, + ), + self.update_product: gapic_v1.method.wrap_method( + self.update_product, + default_timeout=None, + client_info=client_info, + ), + self.delete_product: gapic_v1.method.wrap_method( + self.delete_product, + default_timeout=None, + client_info=client_info, + ), + self.purge_products: gapic_v1.method.wrap_method( + self.purge_products, + default_timeout=None, + client_info=client_info, + ), + self.import_products: gapic_v1.method.wrap_method( + self.import_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.0, + client_info=client_info, + ), + self.set_inventory: gapic_v1.method.wrap_method( + self.set_inventory, + default_timeout=None, + client_info=client_info, + ), + self.add_fulfillment_places: gapic_v1.method.wrap_method( + self.add_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + self.remove_fulfillment_places: gapic_v1.method.wrap_method( + self.remove_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + self.add_local_inventories: gapic_v1.method.wrap_method( + self.add_local_inventories, + default_timeout=None, + client_info=client_info, + ), + self.remove_local_inventories: gapic_v1.method.wrap_method( + self.remove_local_inventories, + 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(self) -> Callable[ + [product_service.CreateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Union[ + product.Product, + Awaitable[product.Product] + ]]: + raise NotImplementedError() + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Union[ + product_service.ListProductsResponse, + Awaitable[product_service.ListProductsResponse] + ]]: + raise NotImplementedError() + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def purge_products(self) -> Callable[ + [purge_config.PurgeProductsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ProductServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py new file mode 100644 index 00000000..ed308f15 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc.py @@ -0,0 +1,810 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.cloud.retail_v2alpha.types import product_service +from google.cloud.retail_v2alpha.types import purge_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO + + +class ProductServiceGrpcTransport(ProductServiceTransport): + """gRPC backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2alpha.Product] + information of the customer's website. + + 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 = 'retail.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 = 'retail.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(self) -> Callable[ + [product_service.CreateProductRequest], + gcr_product.Product]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + product.Product]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + product_service.ListProductsResponse]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2alpha.Product]s. + + 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.retail.v2alpha.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + gcr_product.Product]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def purge_products(self) -> Callable[ + [purge_config.PurgeProductsRequest], + operations_pb2.Operation]: + r"""Return a callable for the purge products method over gRPC. + + Permanently deletes all selected + [Product][google.cloud.retail.v2alpha.Product]s under a branch. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed offline. Depending on the + number of [Product][google.cloud.retail.v2alpha.Product]s, this + operation could take hours to complete. Before the operation + completes, some [Product][google.cloud.retail.v2alpha.Product]s + may still be returned by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Depending on the number of + [Product][google.cloud.retail.v2alpha.Product]s, this operation + could take hours to complete. To get a sample of + [Product][google.cloud.retail.v2alpha.Product]s that would be + deleted, set + [PurgeProductsRequest.force][google.cloud.retail.v2alpha.PurgeProductsRequest.force] + to false. + + 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.retail.v2alpha.ProductService/PurgeProducts', + request_serializer=purge_config.PurgeProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_products'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2alpha.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2alpha.Product]s to be + successfully updated. + + Returns: + Callable[[~.ImportProductsRequest], + ~.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_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + operations_pb2.Operation]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2alpha.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2alpha.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2alpha.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + Returns: + Callable[[~.SetInventoryRequest], + ~.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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the add fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddFulfillmentPlacesRequest], + ~.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 'add_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveFulfillmentPlacesRequest], + ~.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 'remove_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + operations_pb2.Operation]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + ~.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 'add_local_inventories' not in self._stubs: + self._stubs['add_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/AddLocalInventories', + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_local_inventories'] + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + operations_pb2.Operation]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + ~.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 'remove_local_inventories' not in self._stubs: + self._stubs['remove_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/RemoveLocalInventories', + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_local_inventories'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ProductServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..2c7dfd72 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/grpc_asyncio.py @@ -0,0 +1,809 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.cloud.retail_v2alpha.types import product_service +from google.cloud.retail_v2alpha.types import purge_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ProductServiceGrpcTransport + + +class ProductServiceGrpcAsyncIOTransport(ProductServiceTransport): + """gRPC AsyncIO backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2alpha.Product] + information of the customer's website. + + 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 = 'retail.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 = 'retail.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(self) -> Callable[ + [product_service.CreateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Awaitable[product.Product]]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Awaitable[product_service.ListProductsResponse]]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2alpha.Product]s. + + 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.retail.v2alpha.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2alpha.Product]. + + 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.retail.v2alpha.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def purge_products(self) -> Callable[ + [purge_config.PurgeProductsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the purge products method over gRPC. + + Permanently deletes all selected + [Product][google.cloud.retail.v2alpha.Product]s under a branch. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed offline. Depending on the + number of [Product][google.cloud.retail.v2alpha.Product]s, this + operation could take hours to complete. Before the operation + completes, some [Product][google.cloud.retail.v2alpha.Product]s + may still be returned by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Depending on the number of + [Product][google.cloud.retail.v2alpha.Product]s, this operation + could take hours to complete. To get a sample of + [Product][google.cloud.retail.v2alpha.Product]s that would be + deleted, set + [PurgeProductsRequest.force][google.cloud.retail.v2alpha.PurgeProductsRequest.force] + to false. + + 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.retail.v2alpha.ProductService/PurgeProducts', + request_serializer=purge_config.PurgeProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_products'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2alpha.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2alpha.Product]s to be + successfully updated. + + Returns: + Callable[[~.ImportProductsRequest], + 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_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2alpha.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2alpha.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2alpha.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + Returns: + Callable[[~.SetInventoryRequest], + 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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the add fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddFulfillmentPlacesRequest], + 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 'add_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveFulfillmentPlacesRequest], + 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 'remove_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2alpha.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + 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 'add_local_inventories' not in self._stubs: + self._stubs['add_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/AddLocalInventories', + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_local_inventories'] + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2alpha.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2alpha.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + 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 'remove_local_inventories' not in self._stubs: + self._stubs['remove_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ProductService/RemoveLocalInventories', + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_local_inventories'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ProductServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/rest.py new file mode 100644 index 00000000..9c915bc5 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/product_service/transports/rest.py @@ -0,0 +1,1861 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.cloud.retail_v2alpha.types import product_service +from google.cloud.retail_v2alpha.types import purge_config +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ProductServiceTransport, 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 ProductServiceRestInterceptor: + """Interceptor for ProductService. + + 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 ProductServiceRestTransport. + + .. code-block:: python + class MyCustomProductServiceInterceptor(ProductServiceRestInterceptor): + def pre_add_fulfillment_places(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_fulfillment_places(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_add_local_inventories(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_local_inventories(self, response): + logging.log(f"Received response: {response}") + return response + + 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_delete_product(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_import_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_products(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_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_fulfillment_places(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_fulfillment_places(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_local_inventories(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_local_inventories(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_inventory(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_set_inventory(self, response): + logging.log(f"Received response: {response}") + return response + + 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 + + transport = ProductServiceRestTransport(interceptor=MyCustomProductServiceInterceptor()) + client = ProductServiceClient(transport=transport) + + + """ + def pre_add_fulfillment_places(self, request: product_service.AddFulfillmentPlacesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.AddFulfillmentPlacesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_fulfillment_places + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_add_fulfillment_places(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for add_fulfillment_places + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_add_local_inventories(self, request: product_service.AddLocalInventoriesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.AddLocalInventoriesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_local_inventories + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_add_local_inventories(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for add_local_inventories + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_create_product(self, request: product_service.CreateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_create_product(self, response: gcr_product.Product) -> gcr_product.Product: + """Post-rpc interceptor for create_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_delete_product(self, request: product_service.DeleteProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def pre_get_product(self, request: product_service.GetProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_get_product(self, response: product.Product) -> product.Product: + """Post-rpc interceptor for get_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_import_products(self, request: import_config.ImportProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_import_products(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_products + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_list_products(self, request: product_service.ListProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_list_products(self, response: product_service.ListProductsResponse) -> product_service.ListProductsResponse: + """Post-rpc interceptor for list_products + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_purge_products(self, request: purge_config.PurgeProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[purge_config.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 ProductService 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 ProductService server but before + it is returned to user code. + """ + return response + def pre_remove_fulfillment_places(self, request: product_service.RemoveFulfillmentPlacesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.RemoveFulfillmentPlacesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_fulfillment_places + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_remove_fulfillment_places(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for remove_fulfillment_places + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_remove_local_inventories(self, request: product_service.RemoveLocalInventoriesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.RemoveLocalInventoriesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_local_inventories + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_remove_local_inventories(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for remove_local_inventories + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_set_inventory(self, request: product_service.SetInventoryRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.SetInventoryRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_inventory + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_set_inventory(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for set_inventory + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_update_product(self, request: product_service.UpdateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_update_product(self, response: gcr_product.Product) -> gcr_product.Product: + """Post-rpc interceptor for update_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ProductServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ProductServiceRestInterceptor + + +class ProductServiceRestTransport(ProductServiceTransport): + """REST backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2alpha.Product] + information of the customer's website. + + 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 = 'retail.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[ProductServiceRestInterceptor] = 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 ProductServiceRestInterceptor() + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/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="v2alpha") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AddFulfillmentPlaces(ProductServiceRestStub): + def __hash__(self): + return hash("AddFulfillmentPlaces") + + __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_service.AddFulfillmentPlacesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the add fulfillment places method over HTTP. + + Args: + request (~.product_service.AddFulfillmentPlacesRequest): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + 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': '/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addFulfillmentPlaces', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_fulfillment_places(request, metadata) + pb_request = product_service.AddFulfillmentPlacesRequest.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_add_fulfillment_places(resp) + return resp + + class _AddLocalInventories(ProductServiceRestStub): + def __hash__(self): + return hash("AddLocalInventories") + + __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_service.AddLocalInventoriesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the add local inventories method over HTTP. + + Args: + request (~.product_service.AddLocalInventoriesRequest): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + 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': '/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addLocalInventories', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_local_inventories(request, metadata) + pb_request = product_service.AddLocalInventoriesRequest.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_add_local_inventories(resp) + return resp + + class _CreateProduct(ProductServiceRestStub): + def __hash__(self): + return hash("CreateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "productId" : "", } + + @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_service.CreateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_product.Product: + r"""Call the create product method over HTTP. + + Args: + request (~.product_service.CreateProductRequest): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.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: + ~.gcr_product.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*/branches/*}/products', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_create_product(request, metadata) + pb_request = product_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 = gcr_product.Product() + pb_resp = gcr_product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product(resp) + return resp + + class _DeleteProduct(ProductServiceRestStub): + 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_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_service.DeleteProductRequest): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2alpha.ProductService.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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + }, + ] + request, metadata = self._interceptor.pre_delete_product(request, metadata) + pb_request = product_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 _GetProduct(ProductServiceRestStub): + 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_service.GetProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product.Product: + r"""Call the get product method over HTTP. + + Args: + request (~.product_service.GetProductRequest): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.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.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + }, + ] + request, metadata = self._interceptor.pre_get_product(request, metadata) + pb_request = product_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.Product() + pb_resp = product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product(resp) + return resp + + class _ImportProducts(ProductServiceRestStub): + def __hash__(self): + return hash("ImportProducts") + + __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: import_config.ImportProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import products method over HTTP. + + Args: + request (~.import_config.ImportProductsRequest): + The request object. Request message for Import methods. + 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*/branches/*}/products:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_products(request, metadata) + pb_request = import_config.ImportProductsRequest.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_products(resp) + return resp + + class _ListProducts(ProductServiceRestStub): + 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_service.ListProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_service.ListProductsResponse: + r"""Call the list products method over HTTP. + + Args: + request (~.product_service.ListProductsRequest): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.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_service.ListProductsResponse: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*/branches/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products(request, metadata) + pb_request = product_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_service.ListProductsResponse() + pb_resp = product_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 _PurgeProducts(ProductServiceRestStub): + 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: purge_config.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 (~.purge_config.PurgeProductsRequest): + The request object. Request message for 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*/branches/*}/products:purge', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_purge_products(request, metadata) + pb_request = purge_config.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 _RemoveFulfillmentPlaces(ProductServiceRestStub): + def __hash__(self): + return hash("RemoveFulfillmentPlaces") + + __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_service.RemoveFulfillmentPlacesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the remove fulfillment places method over HTTP. + + Args: + request (~.product_service.RemoveFulfillmentPlacesRequest): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + 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': '/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeFulfillmentPlaces', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_fulfillment_places(request, metadata) + pb_request = product_service.RemoveFulfillmentPlacesRequest.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_remove_fulfillment_places(resp) + return resp + + class _RemoveLocalInventories(ProductServiceRestStub): + def __hash__(self): + return hash("RemoveLocalInventories") + + __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_service.RemoveLocalInventoriesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the remove local inventories method over HTTP. + + Args: + request (~.product_service.RemoveLocalInventoriesRequest): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + 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': '/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeLocalInventories', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_local_inventories(request, metadata) + pb_request = product_service.RemoveLocalInventoriesRequest.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_remove_local_inventories(resp) + return resp + + class _SetInventory(ProductServiceRestStub): + def __hash__(self): + return hash("SetInventory") + + __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_service.SetInventoryRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the set inventory method over HTTP. + + Args: + request (~.product_service.SetInventoryRequest): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + 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': '/v2alpha/{inventory.name=projects/*/locations/*/catalogs/*/branches/*/products/**}:setInventory', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_set_inventory(request, metadata) + pb_request = product_service.SetInventoryRequest.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_set_inventory(resp) + return resp + + class _UpdateProduct(ProductServiceRestStub): + 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_service.UpdateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_product.Product: + r"""Call the update product method over HTTP. + + Args: + request (~.product_service.UpdateProductRequest): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.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: + ~.gcr_product.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2alpha/{product.name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_update_product(request, metadata) + pb_request = product_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 = gcr_product.Product() + pb_resp = gcr_product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product(resp) + return resp + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + 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._AddFulfillmentPlaces(self._session, self._host, self._interceptor) # type: ignore + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + 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._AddLocalInventories(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product(self) -> Callable[ + [product_service.CreateProductRequest], + gcr_product.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 delete_product(self) -> Callable[ + [product_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 get_product(self) -> Callable[ + [product_service.GetProductRequest], + product.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 import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + 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._ImportProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + product_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 purge_products(self) -> Callable[ + [purge_config.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_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + 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._RemoveFulfillmentPlaces(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + 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._RemoveLocalInventories(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + 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._SetInventory(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + gcr_product.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 get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ProductServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ProductServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ProductServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/__init__.py new file mode 100644 index 00000000..0355170e --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/__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 SearchServiceClient +from .async_client import SearchServiceAsyncClient + +__all__ = ( + 'SearchServiceClient', + 'SearchServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/async_client.py new file mode 100644 index 00000000..207dbafc --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/async_client.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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.search_service import pagers +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .client import SearchServiceClient + + +class SearchServiceAsyncClient: + """Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + _client: SearchServiceClient + + DEFAULT_ENDPOINT = SearchServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SearchServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(SearchServiceClient.branch_path) + parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) + experiment_path = staticmethod(SearchServiceClient.experiment_path) + parse_experiment_path = staticmethod(SearchServiceClient.parse_experiment_path) + product_path = staticmethod(SearchServiceClient.product_path) + parse_product_path = staticmethod(SearchServiceClient.parse_product_path) + serving_config_path = staticmethod(SearchServiceClient.serving_config_path) + parse_serving_config_path = staticmethod(SearchServiceClient.parse_serving_config_path) + common_billing_account_path = staticmethod(SearchServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(SearchServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(SearchServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(SearchServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(SearchServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(SearchServiceClient.parse_common_organization_path) + common_project_path = staticmethod(SearchServiceClient.common_project_path) + parse_common_project_path = staticmethod(SearchServiceClient.parse_common_project_path) + common_location_path = staticmethod(SearchServiceClient.common_location_path) + parse_common_location_path = staticmethod(SearchServiceClient.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: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_info.__func__(SearchServiceAsyncClient, 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: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_file.__func__(SearchServiceAsyncClient, 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 SearchServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(SearchServiceClient).get_transport_class, type(SearchServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SearchServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service 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, ~.SearchServiceTransport]): 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 = SearchServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def search(self, + request: Optional[Union[search_service.SearchRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchAsyncPager: + r"""Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2alpha + + async def sample_search(): + # Create a client + client = retail_v2alpha.SearchServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.SearchRequest, dict]]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + 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: + google.cloud.retail_v2alpha.services.search_service.pagers.SearchAsyncPager: + Response message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.search, + 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(( + ("placement", request.placement), + )), + ) + + # 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.SearchAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SearchServiceAsyncClient": + 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__ = ( + "SearchServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/client.py new file mode 100644 index 00000000..1cd3ba5a --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/client.py @@ -0,0 +1,649 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.search_service import pagers +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import SearchServiceGrpcTransport +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .transports.rest import SearchServiceRestTransport + + +class SearchServiceClientMeta(type): + """Metaclass for the SearchService 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[SearchServiceTransport]] + _transport_registry["grpc"] = SearchServiceGrpcTransport + _transport_registry["grpc_asyncio"] = SearchServiceGrpcAsyncIOTransport + _transport_registry["rest"] = SearchServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[SearchServiceTransport]: + """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 SearchServiceClient(metaclass=SearchServiceClientMeta): + """Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + @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 = "retail.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: + SearchServiceClient: 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: + SearchServiceClient: 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) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path(project: str,location: str,catalog: str,experiment: str,) -> str: + """Returns a fully-qualified experiment string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format(project=project, location=location, catalog=catalog, experiment=experiment, ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str,str]: + """Parses a experiment path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/experiments/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def serving_config_path(project: str,location: str,catalog: str,serving_config: str,) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str,str]: + """Parses a serving_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?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, SearchServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service 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, SearchServiceTransport]): 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, SearchServiceTransport): + # transport is a SearchServiceTransport 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 search(self, + request: Optional[Union[search_service.SearchRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchPager: + r"""Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2alpha + + def sample_search(): + # Create a client + client = retail_v2alpha.SearchServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.SearchRequest, dict]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + 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: + google.cloud.retail_v2alpha.services.search_service.pagers.SearchPager: + Response message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a search_service.SearchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, search_service.SearchRequest): + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # 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.SearchPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SearchServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "SearchServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/pagers.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/pagers.py new file mode 100644 index 00000000..4cbb60a4 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/pagers.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import search_service + + +class SearchPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.SearchResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.SearchResponse` + 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[..., search_service.SearchResponse], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + 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.retail_v2alpha.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.SearchResponse): + 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 = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[search_service.SearchResponse]: + 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[search_service.SearchResponse.SearchResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class SearchAsyncPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.SearchResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.SearchResponse` + 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[search_service.SearchResponse]], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + 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.retail_v2alpha.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.SearchResponse): + 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 = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[search_service.SearchResponse]: + 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[search_service.SearchResponse.SearchResult]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + 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/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/__init__.py new file mode 100644 index 00000000..4282aef0 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/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 SearchServiceTransport +from .grpc import SearchServiceGrpcTransport +from .grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .rest import SearchServiceRestTransport +from .rest import SearchServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[SearchServiceTransport]] +_transport_registry['grpc'] = SearchServiceGrpcTransport +_transport_registry['grpc_asyncio'] = SearchServiceGrpcAsyncIOTransport +_transport_registry['rest'] = SearchServiceRestTransport + +__all__ = ( + 'SearchServiceTransport', + 'SearchServiceGrpcTransport', + 'SearchServiceGrpcAsyncIOTransport', + 'SearchServiceRestTransport', + 'SearchServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/base.py new file mode 100644 index 00000000..4cb4e7a0 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/base.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class SearchServiceTransport(abc.ABC): + """Abstract transport class for SearchService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.search: gapic_v1.method.wrap_method( + self.search, + 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 search(self) -> Callable[ + [search_service.SearchRequest], + Union[ + search_service.SearchResponse, + Awaitable[search_service.SearchResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'SearchServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc.py new file mode 100644 index 00000000..3abfba6a --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc.py @@ -0,0 +1,310 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO + + +class SearchServiceGrpcTransport(SearchServiceTransport): + """gRPC backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 search(self) -> Callable[ + [search_service.SearchRequest], + search_service.SearchResponse]: + r"""Return a callable for the search method over gRPC. + + Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.SearchRequest], + ~.SearchResponse]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'SearchServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..744b47a8 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/grpc_asyncio.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import SearchServiceGrpcTransport + + +class SearchServiceGrpcAsyncIOTransport(SearchServiceTransport): + """gRPC AsyncIO backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 search(self) -> Callable[ + [search_service.SearchRequest], + Awaitable[search_service.SearchResponse]]: + r"""Return a callable for the search method over gRPC. + + Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.SearchRequest], + Awaitable[~.SearchResponse]]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'SearchServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/rest.py new file mode 100644 index 00000000..7ce0d91e --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/search_service/transports/rest.py @@ -0,0 +1,508 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import SearchServiceTransport, 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 SearchServiceRestInterceptor: + """Interceptor for SearchService. + + 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 SearchServiceRestTransport. + + .. code-block:: python + class MyCustomSearchServiceInterceptor(SearchServiceRestInterceptor): + def pre_search(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_search(self, response): + logging.log(f"Received response: {response}") + return response + + transport = SearchServiceRestTransport(interceptor=MyCustomSearchServiceInterceptor()) + client = SearchServiceClient(transport=transport) + + + """ + def pre_search(self, request: search_service.SearchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[search_service.SearchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for search + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_search(self, response: search_service.SearchResponse) -> search_service.SearchResponse: + """Post-rpc interceptor for search + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class SearchServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: SearchServiceRestInterceptor + + +class SearchServiceRestTransport(SearchServiceTransport): + """REST backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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[SearchServiceRestInterceptor] = 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 SearchServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _Search(SearchServiceRestStub): + def __hash__(self): + return hash("Search") + + __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: search_service.SearchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> search_service.SearchResponse: + r"""Call the search method over HTTP. + + Args: + request (~.search_service.SearchRequest): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + 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: + ~.search_service.SearchResponse: + Response message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{placement=projects/*/locations/*/catalogs/*/placements/*}:search', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v2alpha/{placement=projects/*/locations/*/catalogs/*/servingConfigs/*}:search', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_search(request, metadata) + pb_request = search_service.SearchRequest.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 = search_service.SearchResponse() + pb_resp = search_service.SearchResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_search(resp) + return resp + + @property + def search(self) -> Callable[ + [search_service.SearchRequest], + search_service.SearchResponse]: + # 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._Search(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(SearchServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(SearchServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'SearchServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/__init__.py new file mode 100644 index 00000000..3d167dee --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/__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 ServingConfigServiceClient +from .async_client import ServingConfigServiceAsyncClient + +__all__ = ( + 'ServingConfigServiceClient', + 'ServingConfigServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/async_client.py new file mode 100644 index 00000000..b1ea8da1 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/async_client.py @@ -0,0 +1,1098 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.serving_config_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import search_service +from google.cloud.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config as gcr_serving_config +from google.cloud.retail_v2alpha.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .client import ServingConfigServiceClient + + +class ServingConfigServiceAsyncClient: + """Service for modifying ServingConfig.""" + + _client: ServingConfigServiceClient + + DEFAULT_ENDPOINT = ServingConfigServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ServingConfigServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ServingConfigServiceClient.catalog_path) + parse_catalog_path = staticmethod(ServingConfigServiceClient.parse_catalog_path) + serving_config_path = staticmethod(ServingConfigServiceClient.serving_config_path) + parse_serving_config_path = staticmethod(ServingConfigServiceClient.parse_serving_config_path) + common_billing_account_path = staticmethod(ServingConfigServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ServingConfigServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ServingConfigServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ServingConfigServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ServingConfigServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ServingConfigServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ServingConfigServiceClient.common_project_path) + parse_common_project_path = staticmethod(ServingConfigServiceClient.parse_common_project_path) + common_location_path = staticmethod(ServingConfigServiceClient.common_location_path) + parse_common_location_path = staticmethod(ServingConfigServiceClient.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: + ServingConfigServiceAsyncClient: The constructed client. + """ + return ServingConfigServiceClient.from_service_account_info.__func__(ServingConfigServiceAsyncClient, 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: + ServingConfigServiceAsyncClient: The constructed client. + """ + return ServingConfigServiceClient.from_service_account_file.__func__(ServingConfigServiceAsyncClient, 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 ServingConfigServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ServingConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ServingConfigServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ServingConfigServiceClient).get_transport_class, type(ServingConfigServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ServingConfigServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the serving config service 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, ~.ServingConfigServiceTransport]): 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 = ServingConfigServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_serving_config(self, + request: Optional[Union[serving_config_service.CreateServingConfigRequest, dict]] = None, + *, + parent: Optional[str] = None, + serving_config: Optional[gcr_serving_config.ServingConfig] = None, + serving_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2alpha.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + .. 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 retail_v2alpha + + async def sample_create_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = await client.create_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CreateServingConfigRequest, dict]]): + The request object. Request for CreateServingConfig + method. + parent (:class:`str`): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config (:class:`google.cloud.retail_v2alpha.types.ServingConfig`): + Required. The ServingConfig to + create. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config_id (:class:`str`): + Required. The ID to use for the ServingConfig, which + will become the final component of the ServingConfig's + resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``serving_config_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.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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, serving_config, serving_config_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 = serving_config_service.CreateServingConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if serving_config is not None: + request.serving_config = serving_config + if serving_config_id is not None: + request.serving_config_id = serving_config_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_serving_config, + 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, + ) + + # Done; return the response. + return response + + async def delete_serving_config(self, + request: Optional[Union[serving_config_service.DeleteServingConfigRequest, 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"""Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2alpha + + async def sample_delete_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_serving_config(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.DeleteServingConfigRequest, dict]]): + The request object. Request for DeleteServingConfig + method. + name (:class:`str`): + Required. The resource name of the ServingConfig to + delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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 = serving_config_service.DeleteServingConfigRequest(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_serving_config, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_serving_config(self, + request: Optional[Union[serving_config_service.UpdateServingConfigRequest, dict]] = None, + *, + serving_config: Optional[gcr_serving_config.ServingConfig] = 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]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Updates a ServingConfig. + + .. 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 retail_v2alpha + + async def sample_update_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = await client.update_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.UpdateServingConfigRequest, dict]]): + The request object. Request for UpdateServingConfig + method. + serving_config (:class:`google.cloud.retail_v2alpha.types.ServingConfig`): + Required. The ServingConfig to + update. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + to update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2alpha.ServingConfig.name] + + If not set, all supported fields are updated. + + 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.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_config, 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 = serving_config_service.UpdateServingConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + 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_serving_config, + 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(( + ("serving_config.name", request.serving_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_serving_config(self, + request: Optional[Union[serving_config_service.GetServingConfigRequest, 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]] = (), + ) -> serving_config.ServingConfig: + r"""Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2alpha + + async def sample_get_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.GetServingConfigRequest, dict]]): + The request object. Request for GetServingConfig method. + name (:class:`str`): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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 = serving_config_service.GetServingConfigRequest(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_serving_config, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_serving_configs(self, + request: Optional[Union[serving_config_service.ListServingConfigsRequest, 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.ListServingConfigsAsyncPager: + r"""Lists all ServingConfigs linked to this catalog. + + .. 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 retail_v2alpha + + async def sample_list_serving_configs(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ListServingConfigsRequest, dict]]): + The request object. Request for ListServingConfigs + method. + parent (:class:`str`): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2alpha.services.serving_config_service.pagers.ListServingConfigsAsyncPager: + Response for ListServingConfigs + 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 = serving_config_service.ListServingConfigsRequest(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_serving_configs, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListServingConfigsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_control(self, + request: Optional[Union[serving_config_service.AddControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + .. 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 retail_v2alpha + + async def sample_add_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.add_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.AddControlRequest, dict]]): + The request object. Request for AddControl method. + serving_config (:class:`str`): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 = serving_config_service.AddControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_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.add_control, + 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(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_control(self, + request: Optional[Union[serving_config_service.RemoveControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + .. 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 retail_v2alpha + + async def sample_remove_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.remove_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.RemoveControlRequest, dict]]): + The request object. Request for RemoveControl method. + serving_config (:class:`str`): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 = serving_config_service.RemoveControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_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.remove_control, + 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(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ServingConfigServiceAsyncClient": + 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__ = ( + "ServingConfigServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/client.py new file mode 100644 index 00000000..7a3c06de --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/client.py @@ -0,0 +1,1314 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.services.serving_config_service import pagers +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import search_service +from google.cloud.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config as gcr_serving_config +from google.cloud.retail_v2alpha.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ServingConfigServiceGrpcTransport +from .transports.grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .transports.rest import ServingConfigServiceRestTransport + + +class ServingConfigServiceClientMeta(type): + """Metaclass for the ServingConfigService 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[ServingConfigServiceTransport]] + _transport_registry["grpc"] = ServingConfigServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ServingConfigServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ServingConfigServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ServingConfigServiceTransport]: + """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 ServingConfigServiceClient(metaclass=ServingConfigServiceClientMeta): + """Service for modifying ServingConfig.""" + + @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 = "retail.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: + ServingConfigServiceClient: 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: + ServingConfigServiceClient: 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) -> ServingConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ServingConfigServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def serving_config_path(project: str,location: str,catalog: str,serving_config: str,) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str,str]: + """Parses a serving_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?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, ServingConfigServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the serving config service 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, ServingConfigServiceTransport]): 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, ServingConfigServiceTransport): + # transport is a ServingConfigServiceTransport 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_serving_config(self, + request: Optional[Union[serving_config_service.CreateServingConfigRequest, dict]] = None, + *, + parent: Optional[str] = None, + serving_config: Optional[gcr_serving_config.ServingConfig] = None, + serving_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2alpha.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + .. 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 retail_v2alpha + + def sample_create_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = client.create_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CreateServingConfigRequest, dict]): + The request object. Request for CreateServingConfig + method. + parent (str): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config (google.cloud.retail_v2alpha.types.ServingConfig): + Required. The ServingConfig to + create. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config_id (str): + Required. The ID to use for the ServingConfig, which + will become the final component of the ServingConfig's + resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``serving_config_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.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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, serving_config, serving_config_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 serving_config_service.CreateServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.CreateServingConfigRequest): + request = serving_config_service.CreateServingConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if serving_config is not None: + request.serving_config = serving_config + if serving_config_id is not None: + request.serving_config_id = serving_config_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_serving_config] + + # 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_serving_config(self, + request: Optional[Union[serving_config_service.DeleteServingConfigRequest, 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"""Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2alpha + + def sample_delete_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_serving_config(request=request) + + Args: + request (Union[google.cloud.retail_v2alpha.types.DeleteServingConfigRequest, dict]): + The request object. Request for DeleteServingConfig + method. + name (str): + Required. The resource name of the ServingConfig to + delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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 serving_config_service.DeleteServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.DeleteServingConfigRequest): + request = serving_config_service.DeleteServingConfigRequest(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_serving_config] + + # 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 update_serving_config(self, + request: Optional[Union[serving_config_service.UpdateServingConfigRequest, dict]] = None, + *, + serving_config: Optional[gcr_serving_config.ServingConfig] = 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]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Updates a ServingConfig. + + .. 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 retail_v2alpha + + def sample_update_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = client.update_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.UpdateServingConfigRequest, dict]): + The request object. Request for UpdateServingConfig + method. + serving_config (google.cloud.retail_v2alpha.types.ServingConfig): + Required. The ServingConfig to + update. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + to update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2alpha.ServingConfig.name] + + If not set, all supported fields are updated. + + 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.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_config, 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 serving_config_service.UpdateServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.UpdateServingConfigRequest): + request = serving_config_service.UpdateServingConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + 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_serving_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config.name", request.serving_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_serving_config(self, + request: Optional[Union[serving_config_service.GetServingConfigRequest, 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]] = (), + ) -> serving_config.ServingConfig: + r"""Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2alpha + + def sample_get_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.GetServingConfigRequest, dict]): + The request object. Request for GetServingConfig method. + name (str): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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 serving_config_service.GetServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.GetServingConfigRequest): + request = serving_config_service.GetServingConfigRequest(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_serving_config] + + # 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 list_serving_configs(self, + request: Optional[Union[serving_config_service.ListServingConfigsRequest, 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.ListServingConfigsPager: + r"""Lists all ServingConfigs linked to this catalog. + + .. 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 retail_v2alpha + + def sample_list_serving_configs(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ListServingConfigsRequest, dict]): + The request object. Request for ListServingConfigs + method. + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2alpha.services.serving_config_service.pagers.ListServingConfigsPager: + Response for ListServingConfigs + 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 serving_config_service.ListServingConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.ListServingConfigsRequest): + request = serving_config_service.ListServingConfigsRequest(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_serving_configs] + + # 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.ListServingConfigsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_control(self, + request: Optional[Union[serving_config_service.AddControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + .. 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 retail_v2alpha + + def sample_add_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.add_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.AddControlRequest, dict]): + The request object. Request for AddControl method. + serving_config (str): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 serving_config_service.AddControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.AddControlRequest): + request = serving_config_service.AddControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_control(self, + request: Optional[Union[serving_config_service.RemoveControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + .. 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 retail_v2alpha + + def sample_remove_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.remove_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.RemoveControlRequest, dict]): + The request object. Request for RemoveControl method. + serving_config (str): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2alpha.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 serving_config_service.RemoveControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.RemoveControlRequest): + request = serving_config_service.RemoveControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ServingConfigServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ServingConfigServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/pagers.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/pagers.py new file mode 100644 index 00000000..254440ba --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config_service + + +class ListServingConfigsPager: + """A pager for iterating through ``list_serving_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListServingConfigsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``serving_configs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListServingConfigs`` requests and continue to iterate + through the ``serving_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListServingConfigsResponse` + 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[..., serving_config_service.ListServingConfigsResponse], + request: serving_config_service.ListServingConfigsRequest, + response: serving_config_service.ListServingConfigsResponse, + *, + 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.retail_v2alpha.types.ListServingConfigsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListServingConfigsResponse): + 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 = serving_config_service.ListServingConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[serving_config_service.ListServingConfigsResponse]: + 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[serving_config.ServingConfig]: + for page in self.pages: + yield from page.serving_configs + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListServingConfigsAsyncPager: + """A pager for iterating through ``list_serving_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2alpha.types.ListServingConfigsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``serving_configs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListServingConfigs`` requests and continue to iterate + through the ``serving_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2alpha.types.ListServingConfigsResponse` + 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[serving_config_service.ListServingConfigsResponse]], + request: serving_config_service.ListServingConfigsRequest, + response: serving_config_service.ListServingConfigsResponse, + *, + 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.retail_v2alpha.types.ListServingConfigsRequest): + The initial request object. + response (google.cloud.retail_v2alpha.types.ListServingConfigsResponse): + 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 = serving_config_service.ListServingConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[serving_config_service.ListServingConfigsResponse]: + 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[serving_config.ServingConfig]: + async def async_generator(): + async for page in self.pages: + for response in page.serving_configs: + 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/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/__init__.py new file mode 100644 index 00000000..e0440c46 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/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 ServingConfigServiceTransport +from .grpc import ServingConfigServiceGrpcTransport +from .grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .rest import ServingConfigServiceRestTransport +from .rest import ServingConfigServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ServingConfigServiceTransport]] +_transport_registry['grpc'] = ServingConfigServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ServingConfigServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ServingConfigServiceRestTransport + +__all__ = ( + 'ServingConfigServiceTransport', + 'ServingConfigServiceGrpcTransport', + 'ServingConfigServiceGrpcAsyncIOTransport', + 'ServingConfigServiceRestTransport', + 'ServingConfigServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/base.py new file mode 100644 index 00000000..7deccc2e --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/base.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config as gcr_serving_config +from google.cloud.retail_v2alpha.types import serving_config_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 ServingConfigServiceTransport(abc.ABC): + """Abstract transport class for ServingConfigService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_serving_config: gapic_v1.method.wrap_method( + self.create_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.delete_serving_config: gapic_v1.method.wrap_method( + self.delete_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.update_serving_config: gapic_v1.method.wrap_method( + self.update_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.get_serving_config: gapic_v1.method.wrap_method( + self.get_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.list_serving_configs: gapic_v1.method.wrap_method( + self.list_serving_configs, + default_timeout=None, + client_info=client_info, + ), + self.add_control: gapic_v1.method.wrap_method( + self.add_control, + default_timeout=None, + client_info=client_info, + ), + self.remove_control: gapic_v1.method.wrap_method( + self.remove_control, + 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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + Union[ + serving_config.ServingConfig, + Awaitable[serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + Union[ + serving_config_service.ListServingConfigsResponse, + Awaitable[serving_config_service.ListServingConfigsResponse] + ]]: + raise NotImplementedError() + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ServingConfigServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc.py new file mode 100644 index 00000000..58e7d8b0 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc.py @@ -0,0 +1,480 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config as gcr_serving_config +from google.cloud.retail_v2alpha.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO + + +class ServingConfigServiceGrpcTransport(ServingConfigServiceTransport): + """gRPC backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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 = 'retail.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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the create serving config method over gRPC. + + Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2alpha.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + Returns: + Callable[[~.CreateServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['create_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/CreateServingConfig', + request_serializer=serving_config_service.CreateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['create_serving_config'] + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete serving config method over gRPC. + + Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.DeleteServingConfigRequest], + ~.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_serving_config' not in self._stubs: + self._stubs['delete_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/DeleteServingConfig', + request_serializer=serving_config_service.DeleteServingConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_serving_config'] + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the update serving config method over gRPC. + + Updates a ServingConfig. + + Returns: + Callable[[~.UpdateServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['update_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/UpdateServingConfig', + request_serializer=serving_config_service.UpdateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['update_serving_config'] + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + serving_config.ServingConfig]: + r"""Return a callable for the get serving config method over gRPC. + + Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.GetServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['get_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/GetServingConfig', + request_serializer=serving_config_service.GetServingConfigRequest.serialize, + response_deserializer=serving_config.ServingConfig.deserialize, + ) + return self._stubs['get_serving_config'] + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + serving_config_service.ListServingConfigsResponse]: + r"""Return a callable for the list serving configs method over gRPC. + + Lists all ServingConfigs linked to this catalog. + + Returns: + Callable[[~.ListServingConfigsRequest], + ~.ListServingConfigsResponse]: + 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_serving_configs' not in self._stubs: + self._stubs['list_serving_configs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/ListServingConfigs', + request_serializer=serving_config_service.ListServingConfigsRequest.serialize, + response_deserializer=serving_config_service.ListServingConfigsResponse.deserialize, + ) + return self._stubs['list_serving_configs'] + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the add control method over gRPC. + + Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + Returns: + Callable[[~.AddControlRequest], + ~.ServingConfig]: + 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_control' not in self._stubs: + self._stubs['add_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/AddControl', + request_serializer=serving_config_service.AddControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['add_control'] + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the remove control method over gRPC. + + Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + Returns: + Callable[[~.RemoveControlRequest], + ~.ServingConfig]: + 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_control' not in self._stubs: + self._stubs['remove_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/RemoveControl', + request_serializer=serving_config_service.RemoveControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['remove_control'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ServingConfigServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..ce4e330c --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/grpc_asyncio.py @@ -0,0 +1,479 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config as gcr_serving_config +from google.cloud.retail_v2alpha.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ServingConfigServiceGrpcTransport + + +class ServingConfigServiceGrpcAsyncIOTransport(ServingConfigServiceTransport): + """gRPC AsyncIO backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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 = 'retail.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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the create serving config method over gRPC. + + Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2alpha.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + Returns: + Callable[[~.CreateServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['create_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/CreateServingConfig', + request_serializer=serving_config_service.CreateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['create_serving_config'] + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete serving config method over gRPC. + + Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.DeleteServingConfigRequest], + 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_serving_config' not in self._stubs: + self._stubs['delete_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/DeleteServingConfig', + request_serializer=serving_config_service.DeleteServingConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_serving_config'] + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the update serving config method over gRPC. + + Updates a ServingConfig. + + Returns: + Callable[[~.UpdateServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['update_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/UpdateServingConfig', + request_serializer=serving_config_service.UpdateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['update_serving_config'] + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + Awaitable[serving_config.ServingConfig]]: + r"""Return a callable for the get serving config method over gRPC. + + Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.GetServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['get_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/GetServingConfig', + request_serializer=serving_config_service.GetServingConfigRequest.serialize, + response_deserializer=serving_config.ServingConfig.deserialize, + ) + return self._stubs['get_serving_config'] + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + Awaitable[serving_config_service.ListServingConfigsResponse]]: + r"""Return a callable for the list serving configs method over gRPC. + + Lists all ServingConfigs linked to this catalog. + + Returns: + Callable[[~.ListServingConfigsRequest], + Awaitable[~.ListServingConfigsResponse]]: + 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_serving_configs' not in self._stubs: + self._stubs['list_serving_configs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/ListServingConfigs', + request_serializer=serving_config_service.ListServingConfigsRequest.serialize, + response_deserializer=serving_config_service.ListServingConfigsResponse.deserialize, + ) + return self._stubs['list_serving_configs'] + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the add control method over gRPC. + + Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + Returns: + Callable[[~.AddControlRequest], + Awaitable[~.ServingConfig]]: + 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_control' not in self._stubs: + self._stubs['add_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/AddControl', + request_serializer=serving_config_service.AddControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['add_control'] + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the remove control method over gRPC. + + Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + Returns: + Callable[[~.RemoveControlRequest], + Awaitable[~.ServingConfig]]: + 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_control' not in self._stubs: + self._stubs['remove_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.ServingConfigService/RemoveControl', + request_serializer=serving_config_service.RemoveControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['remove_control'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ServingConfigServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/rest.py new file mode 100644 index 00000000..2828cd18 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/serving_config_service/transports/rest.py @@ -0,0 +1,1186 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config as gcr_serving_config +from google.cloud.retail_v2alpha.types import serving_config_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ServingConfigServiceTransport, 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 ServingConfigServiceRestInterceptor: + """Interceptor for ServingConfigService. + + 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 ServingConfigServiceRestTransport. + + .. code-block:: python + class MyCustomServingConfigServiceInterceptor(ServingConfigServiceRestInterceptor): + def pre_add_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_serving_configs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_serving_configs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ServingConfigServiceRestTransport(interceptor=MyCustomServingConfigServiceInterceptor()) + client = ServingConfigServiceClient(transport=transport) + + + """ + def pre_add_control(self, request: serving_config_service.AddControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.AddControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_add_control(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for add_control + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_create_serving_config(self, request: serving_config_service.CreateServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.CreateServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_create_serving_config(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for create_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_delete_serving_config(self, request: serving_config_service.DeleteServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.DeleteServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def pre_get_serving_config(self, request: serving_config_service.GetServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.GetServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_get_serving_config(self, response: serving_config.ServingConfig) -> serving_config.ServingConfig: + """Post-rpc interceptor for get_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_list_serving_configs(self, request: serving_config_service.ListServingConfigsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.ListServingConfigsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_serving_configs + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_list_serving_configs(self, response: serving_config_service.ListServingConfigsResponse) -> serving_config_service.ListServingConfigsResponse: + """Post-rpc interceptor for list_serving_configs + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_remove_control(self, request: serving_config_service.RemoveControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.RemoveControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_remove_control(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for remove_control + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_update_serving_config(self, request: serving_config_service.UpdateServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.UpdateServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_update_serving_config(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for update_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ServingConfigServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ServingConfigServiceRestInterceptor + + +class ServingConfigServiceRestTransport(ServingConfigServiceTransport): + """REST backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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[ServingConfigServiceRestInterceptor] = 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 ServingConfigServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _AddControl(ServingConfigServiceRestStub): + def __hash__(self): + return hash("AddControl") + + __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: serving_config_service.AddControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the add control method over HTTP. + + Args: + request (~.serving_config_service.AddControlRequest): + The request object. Request for AddControl 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:addControl', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_control(request, metadata) + pb_request = serving_config_service.AddControlRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_add_control(resp) + return resp + + class _CreateServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("CreateServingConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "servingConfigId" : "", } + + @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: serving_config_service.CreateServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the create serving config method over HTTP. + + Args: + request (~.serving_config_service.CreateServingConfigRequest): + The request object. Request for CreateServingConfig + 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/servingConfigs', + 'body': 'serving_config', + }, + ] + request, metadata = self._interceptor.pre_create_serving_config(request, metadata) + pb_request = serving_config_service.CreateServingConfigRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_serving_config(resp) + return resp + + class _DeleteServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("DeleteServingConfig") + + __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: serving_config_service.DeleteServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete serving config method over HTTP. + + Args: + request (~.serving_config_service.DeleteServingConfigRequest): + The request object. Request for DeleteServingConfig + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_serving_config(request, metadata) + pb_request = serving_config_service.DeleteServingConfigRequest.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 _GetServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("GetServingConfig") + + __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: serving_config_service.GetServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> serving_config.ServingConfig: + r"""Call the get serving config method over HTTP. + + Args: + request (~.serving_config_service.GetServingConfigRequest): + The request object. Request for GetServingConfig 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: + ~.serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + }, + ] + request, metadata = self._interceptor.pre_get_serving_config(request, metadata) + pb_request = serving_config_service.GetServingConfigRequest.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 = serving_config.ServingConfig() + pb_resp = serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_serving_config(resp) + return resp + + class _ListServingConfigs(ServingConfigServiceRestStub): + def __hash__(self): + return hash("ListServingConfigs") + + __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: serving_config_service.ListServingConfigsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> serving_config_service.ListServingConfigsResponse: + r"""Call the list serving configs method over HTTP. + + Args: + request (~.serving_config_service.ListServingConfigsRequest): + The request object. Request for ListServingConfigs + 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: + ~.serving_config_service.ListServingConfigsResponse: + Response for ListServingConfigs + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/servingConfigs', + }, + ] + request, metadata = self._interceptor.pre_list_serving_configs(request, metadata) + pb_request = serving_config_service.ListServingConfigsRequest.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 = serving_config_service.ListServingConfigsResponse() + pb_resp = serving_config_service.ListServingConfigsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_serving_configs(resp) + return resp + + class _RemoveControl(ServingConfigServiceRestStub): + def __hash__(self): + return hash("RemoveControl") + + __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: serving_config_service.RemoveControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the remove control method over HTTP. + + Args: + request (~.serving_config_service.RemoveControlRequest): + The request object. Request for RemoveControl 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:removeControl', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_control(request, metadata) + pb_request = serving_config_service.RemoveControlRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_remove_control(resp) + return resp + + class _UpdateServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("UpdateServingConfig") + + __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: serving_config_service.UpdateServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the update serving config method over HTTP. + + Args: + request (~.serving_config_service.UpdateServingConfigRequest): + The request object. Request for UpdateServingConfig + 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2alpha/{serving_config.name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + 'body': 'serving_config', + }, + ] + request, metadata = self._interceptor.pre_update_serving_config(request, metadata) + pb_request = serving_config_service.UpdateServingConfigRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_serving_config(resp) + return resp + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + gcr_serving_config.ServingConfig]: + # 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._AddControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + gcr_serving_config.ServingConfig]: + # 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._CreateServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + 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._DeleteServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + serving_config.ServingConfig]: + # 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._GetServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + serving_config_service.ListServingConfigsResponse]: + # 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._ListServingConfigs(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + gcr_serving_config.ServingConfig]: + # 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._RemoveControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + gcr_serving_config.ServingConfig]: + # 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._UpdateServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ServingConfigServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ServingConfigServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ServingConfigServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/__init__.py new file mode 100644 index 00000000..387c002d --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/__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 UserEventServiceClient +from .async_client import UserEventServiceAsyncClient + +__all__ = ( + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/async_client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/async_client.py new file mode 100644 index 00000000..59130d76 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/async_client.py @@ -0,0 +1,865 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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 import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import purge_config +from google.cloud.retail_v2alpha.types import user_event +from google.cloud.retail_v2alpha.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .client import UserEventServiceClient + + +class UserEventServiceAsyncClient: + """Service for ingesting end user actions on the customer + website. + """ + + _client: UserEventServiceClient + + DEFAULT_ENDPOINT = UserEventServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = UserEventServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(UserEventServiceClient.catalog_path) + parse_catalog_path = staticmethod(UserEventServiceClient.parse_catalog_path) + product_path = staticmethod(UserEventServiceClient.product_path) + parse_product_path = staticmethod(UserEventServiceClient.parse_product_path) + common_billing_account_path = staticmethod(UserEventServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(UserEventServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(UserEventServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(UserEventServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(UserEventServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(UserEventServiceClient.parse_common_organization_path) + common_project_path = staticmethod(UserEventServiceClient.common_project_path) + parse_common_project_path = staticmethod(UserEventServiceClient.parse_common_project_path) + common_location_path = staticmethod(UserEventServiceClient.common_location_path) + parse_common_location_path = staticmethod(UserEventServiceClient.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: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_info.__func__(UserEventServiceAsyncClient, 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: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_file.__func__(UserEventServiceAsyncClient, 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 UserEventServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(UserEventServiceClient).get_transport_class, type(UserEventServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, UserEventServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service 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, ~.UserEventServiceTransport]): 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 = UserEventServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def write_user_event(self, + request: Optional[Union[user_event_service.WriteUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + .. 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 retail_v2alpha + + async def sample_write_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = await client.write_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.WriteUserEventRequest, dict]]): + The request object. Request message for WriteUserEvent + 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: + google.cloud.retail_v2alpha.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.write_user_event, + 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, + ) + + # Done; return the response. + return response + + async def collect_user_event(self, + request: Optional[Union[user_event_service.CollectUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + .. 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 retail_v2alpha + + async def sample_collect_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = await client.collect_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.CollectUserEventRequest, dict]]): + The request object. Request message for CollectUserEvent + 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: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.collect_user_event, + 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, + ) + + # Done; return the response. + return response + + async def purge_user_events(self, + request: Optional[Union[purge_config.PurgeUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + .. 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 retail_v2alpha + + async def sample_purge_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.PurgeUserEventsRequest, dict]]): + The request object. Request message for PurgeUserEvents + 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: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + request = purge_config.PurgeUserEventsRequest(request) + + # 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_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.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, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + async def import_user_events(self, + request: Optional[Union[import_config.ImportUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + .. 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 retail_v2alpha + + async def sample_import_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2alpha.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.ImportUserEventsRequest, dict]]): + The request object. Request message for the + ImportUserEvents request. + 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.retail_v2alpha.types.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportUserEventsRequest(request) + + # 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_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.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, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def rejoin_user_events(self, + request: Optional[Union[user_event_service.RejoinUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + .. 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 retail_v2alpha + + async def sample_rejoin_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2alpha.types.RejoinUserEventsRequest, dict]]): + The request object. Request message for RejoinUserEvents + 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: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2alpha.types.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.rejoin_user_events, + 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, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "UserEventServiceAsyncClient": + 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__ = ( + "UserEventServiceAsyncClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/client.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/client.py new file mode 100644 index 00000000..0bb9e5df --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/client.py @@ -0,0 +1,1072 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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 import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import purge_config +from google.cloud.retail_v2alpha.types import user_event +from google.cloud.retail_v2alpha.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserEventServiceGrpcTransport +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .transports.rest import UserEventServiceRestTransport + + +class UserEventServiceClientMeta(type): + """Metaclass for the UserEventService 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[UserEventServiceTransport]] + _transport_registry["grpc"] = UserEventServiceGrpcTransport + _transport_registry["grpc_asyncio"] = UserEventServiceGrpcAsyncIOTransport + _transport_registry["rest"] = UserEventServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[UserEventServiceTransport]: + """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 UserEventServiceClient(metaclass=UserEventServiceClientMeta): + """Service for ingesting end user actions on the customer + website. + """ + + @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 = "retail.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: + UserEventServiceClient: 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: + UserEventServiceClient: 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) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, UserEventServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service 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, UserEventServiceTransport]): 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, UserEventServiceTransport): + # transport is a UserEventServiceTransport 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 write_user_event(self, + request: Optional[Union[user_event_service.WriteUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + .. 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 retail_v2alpha + + def sample_write_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = client.write_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.WriteUserEventRequest, dict]): + The request object. Request message for WriteUserEvent + 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: + google.cloud.retail_v2alpha.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.WriteUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.WriteUserEventRequest): + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.write_user_event] + + # 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 collect_user_event(self, + request: Optional[Union[user_event_service.CollectUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + .. 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 retail_v2alpha + + def sample_collect_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = client.collect_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.CollectUserEventRequest, dict]): + The request object. Request message for CollectUserEvent + 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: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.CollectUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.CollectUserEventRequest): + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.collect_user_event] + + # 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 purge_user_events(self, + request: Optional[Union[purge_config.PurgeUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + .. 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 retail_v2alpha + + def sample_purge_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.PurgeUserEventsRequest, dict]): + The request object. Request message for PurgeUserEvents + 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: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2alpha.types.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a purge_config.PurgeUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, purge_config.PurgeUserEventsRequest): + request = purge_config.PurgeUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.purge_user_events] + + # 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, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + def import_user_events(self, + request: Optional[Union[import_config.ImportUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + .. 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 retail_v2alpha + + def sample_import_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2alpha.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.ImportUserEventsRequest, dict]): + The request object. Request message for the + ImportUserEvents request. + 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.retail_v2alpha.types.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportUserEventsRequest): + request = import_config.ImportUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_user_events] + + # 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, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def rejoin_user_events(self, + request: Optional[Union[user_event_service.RejoinUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + .. 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 retail_v2alpha + + def sample_rejoin_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2alpha.types.RejoinUserEventsRequest, dict]): + The request object. Request message for RejoinUserEvents + 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: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2alpha.types.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.RejoinUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.RejoinUserEventsRequest): + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.rejoin_user_events] + + # 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, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "UserEventServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "UserEventServiceClient", +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/__init__.py new file mode 100644 index 00000000..bea95d5a --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/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 UserEventServiceTransport +from .grpc import UserEventServiceGrpcTransport +from .grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .rest import UserEventServiceRestTransport +from .rest import UserEventServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[UserEventServiceTransport]] +_transport_registry['grpc'] = UserEventServiceGrpcTransport +_transport_registry['grpc_asyncio'] = UserEventServiceGrpcAsyncIOTransport +_transport_registry['rest'] = UserEventServiceRestTransport + +__all__ = ( + 'UserEventServiceTransport', + 'UserEventServiceGrpcTransport', + 'UserEventServiceGrpcAsyncIOTransport', + 'UserEventServiceRestTransport', + 'UserEventServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/base.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/base.py new file mode 100644 index 00000000..89f8c7cd --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/base.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha 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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import purge_config +from google.cloud.retail_v2alpha.types import user_event +from google.cloud.retail_v2alpha.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class UserEventServiceTransport(abc.ABC): + """Abstract transport class for UserEventService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.write_user_event: gapic_v1.method.wrap_method( + self.write_user_event, + default_timeout=None, + client_info=client_info, + ), + self.collect_user_event: gapic_v1.method.wrap_method( + self.collect_user_event, + default_timeout=None, + client_info=client_info, + ), + self.purge_user_events: gapic_v1.method.wrap_method( + self.purge_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.import_user_events: gapic_v1.method.wrap_method( + self.import_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.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.rejoin_user_events: gapic_v1.method.wrap_method( + self.rejoin_user_events, + 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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Union[ + user_event.UserEvent, + Awaitable[user_event.UserEvent] + ]]: + raise NotImplementedError() + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Union[ + httpbody_pb2.HttpBody, + Awaitable[httpbody_pb2.HttpBody] + ]]: + raise NotImplementedError() + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'UserEventServiceTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc.py new file mode 100644 index 00000000..6ee0f557 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc.py @@ -0,0 +1,455 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import purge_config +from google.cloud.retail_v2alpha.types import user_event +from google.cloud.retail_v2alpha.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO + + +class UserEventServiceGrpcTransport(UserEventServiceTransport): + """gRPC backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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 = 'retail.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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + user_event.UserEvent]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + ~.UserEvent]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + httpbody_pb2.HttpBody]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + ~.HttpBody]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + ~.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_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + Returns: + Callable[[~.ImportUserEventsRequest], + ~.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_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the rejoin user events method over gRPC. + + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + Returns: + Callable[[~.RejoinUserEventsRequest], + ~.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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'UserEventServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc_asyncio.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..45906c60 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/grpc_asyncio.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. +# +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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import purge_config +from google.cloud.retail_v2alpha.types import user_event +from google.cloud.retail_v2alpha.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import UserEventServiceGrpcTransport + + +class UserEventServiceGrpcAsyncIOTransport(UserEventServiceTransport): + """gRPC AsyncIO backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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 = 'retail.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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Awaitable[user_event.UserEvent]]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + Awaitable[~.UserEvent]]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Awaitable[httpbody_pb2.HttpBody]]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + Awaitable[~.HttpBody]]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + 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_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + Returns: + Callable[[~.ImportUserEventsRequest], + 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_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the rejoin user events method over gRPC. + + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + Returns: + Callable[[~.RejoinUserEventsRequest], + 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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2alpha.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'UserEventServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/rest.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/rest.py new file mode 100644 index 00000000..ff34da9b --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/services/user_event_service/transports/rest.py @@ -0,0 +1,1090 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.api import httpbody_pb2 # type: ignore +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import purge_config +from google.cloud.retail_v2alpha.types import user_event +from google.cloud.retail_v2alpha.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import UserEventServiceTransport, 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 UserEventServiceRestInterceptor: + """Interceptor for UserEventService. + + 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 UserEventServiceRestTransport. + + .. code-block:: python + class MyCustomUserEventServiceInterceptor(UserEventServiceRestInterceptor): + def pre_collect_user_event(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_collect_user_event(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_purge_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_purge_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_rejoin_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_rejoin_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_write_user_event(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_write_user_event(self, response): + logging.log(f"Received response: {response}") + return response + + transport = UserEventServiceRestTransport(interceptor=MyCustomUserEventServiceInterceptor()) + client = UserEventServiceClient(transport=transport) + + + """ + def pre_collect_user_event(self, request: user_event_service.CollectUserEventRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.CollectUserEventRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for collect_user_event + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_collect_user_event(self, response: httpbody_pb2.HttpBody) -> httpbody_pb2.HttpBody: + """Post-rpc interceptor for collect_user_event + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_import_user_events(self, request: import_config.ImportUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_import_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_purge_user_events(self, request: purge_config.PurgeUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[purge_config.PurgeUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for purge_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_purge_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for purge_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_rejoin_user_events(self, request: user_event_service.RejoinUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.RejoinUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for rejoin_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_rejoin_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for rejoin_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_write_user_event(self, request: user_event_service.WriteUserEventRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.WriteUserEventRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for write_user_event + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_write_user_event(self, response: user_event.UserEvent) -> user_event.UserEvent: + """Post-rpc interceptor for write_user_event + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class UserEventServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: UserEventServiceRestInterceptor + + +class UserEventServiceRestTransport(UserEventServiceTransport): + """REST backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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[UserEventServiceRestInterceptor] = 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 UserEventServiceRestInterceptor() + 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': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/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="v2alpha") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CollectUserEvent(UserEventServiceRestStub): + def __hash__(self): + return hash("CollectUserEvent") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "userEvent" : "", } + + @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: user_event_service.CollectUserEventRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> httpbody_pb2.HttpBody: + r"""Call the collect user event method over HTTP. + + Args: + request (~.user_event_service.CollectUserEventRequest): + The request object. Request message for CollectUserEvent + 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: + ~.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It + should only be used for payload formats that can't be + represented as JSON, such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as the + response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request fields + and also want access to the raw HTTP body. + + Example: + + :: + + message GetResourceRequest { + // A unique request id. + string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + :: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/userEvents:collect', + }, + ] + request, metadata = self._interceptor.pre_collect_user_event(request, metadata) + pb_request = user_event_service.CollectUserEventRequest.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 = httpbody_pb2.HttpBody() + pb_resp = resp + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_collect_user_event(resp) + return resp + + class _ImportUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("ImportUserEvents") + + __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: import_config.ImportUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import user events method over HTTP. + + Args: + request (~.import_config.ImportUserEventsRequest): + The request object. Request message for the + ImportUserEvents request. + 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/userEvents:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_user_events(request, metadata) + pb_request = import_config.ImportUserEventsRequest.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_user_events(resp) + return resp + + class _PurgeUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("PurgeUserEvents") + + __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: purge_config.PurgeUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the purge user events method over HTTP. + + Args: + request (~.purge_config.PurgeUserEventsRequest): + The request object. Request message for PurgeUserEvents + 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/userEvents:purge', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_purge_user_events(request, metadata) + pb_request = purge_config.PurgeUserEventsRequest.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_user_events(resp) + return resp + + class _RejoinUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("RejoinUserEvents") + + __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: user_event_service.RejoinUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the rejoin user events method over HTTP. + + Args: + request (~.user_event_service.RejoinUserEventsRequest): + The request object. Request message for RejoinUserEvents + 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': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/userEvents:rejoin', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_rejoin_user_events(request, metadata) + pb_request = user_event_service.RejoinUserEventsRequest.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_rejoin_user_events(resp) + return resp + + class _WriteUserEvent(UserEventServiceRestStub): + def __hash__(self): + return hash("WriteUserEvent") + + __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: user_event_service.WriteUserEventRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> user_event.UserEvent: + r"""Call the write user event method over HTTP. + + Args: + request (~.user_event_service.WriteUserEventRequest): + The request object. Request message for WriteUserEvent + 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: + ~.user_event.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2alpha/{parent=projects/*/locations/*/catalogs/*}/userEvents:write', + 'body': 'user_event', + }, + ] + request, metadata = self._interceptor.pre_write_user_event(request, metadata) + pb_request = user_event_service.WriteUserEventRequest.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 = user_event.UserEvent() + pb_resp = user_event.UserEvent.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_write_user_event(resp) + return resp + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + httpbody_pb2.HttpBody]: + # 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._CollectUserEvent(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + 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._ImportUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + 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._PurgeUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + 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._RejoinUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + user_event.UserEvent]: + # 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._WriteUserEvent(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(UserEventServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/places/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(UserEventServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2alpha/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'UserEventServiceRestTransport', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/__init__.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/__init__.py new file mode 100644 index 00000000..73b28778 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/__init__.py @@ -0,0 +1,348 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 .catalog import ( + AttributesConfig, + Catalog, + CatalogAttribute, + CompletionConfig, + MerchantCenterFeedFilter, + MerchantCenterLink, + MerchantCenterLinkingConfig, + ProductLevelConfig, +) +from .catalog_service import ( + AddCatalogAttributeRequest, + BatchRemoveCatalogAttributesRequest, + BatchRemoveCatalogAttributesResponse, + GetAttributesConfigRequest, + GetCompletionConfigRequest, + GetDefaultBranchRequest, + GetDefaultBranchResponse, + ListCatalogsRequest, + ListCatalogsResponse, + RemoveCatalogAttributeRequest, + ReplaceCatalogAttributeRequest, + SetDefaultBranchRequest, + UpdateAttributesConfigRequest, + UpdateCatalogRequest, + UpdateCompletionConfigRequest, +) +from .common import ( + Audience, + ColorInfo, + Condition, + CustomAttribute, + FulfillmentInfo, + Image, + Interval, + LocalInventory, + PriceInfo, + Rating, + Rule, + UserInfo, + AttributeConfigLevel, + RecommendationsFilteringOption, + SearchSolutionUseCase, + SolutionType, +) +from .completion_service import ( + CompleteQueryRequest, + CompleteQueryResponse, +) +from .control import ( + Control, +) +from .control_service import ( + CreateControlRequest, + DeleteControlRequest, + GetControlRequest, + ListControlsRequest, + ListControlsResponse, + UpdateControlRequest, +) +from .export_config import ( + BigQueryOutputResult, + ExportErrorsConfig, + ExportMetadata, + ExportProductsResponse, + ExportUserEventsResponse, + GcsOutputResult, + OutputResult, +) +from .import_config import ( + BigQuerySource, + CompletionDataInputConfig, + GcsSource, + ImportCompletionDataRequest, + ImportCompletionDataResponse, + ImportErrorsConfig, + ImportMetadata, + ImportProductsRequest, + ImportProductsResponse, + ImportUserEventsRequest, + ImportUserEventsResponse, + ProductInlineSource, + ProductInputConfig, + TransformedUserEventsMetadata, + UserEventImportSummary, + UserEventInlineSource, + UserEventInputConfig, +) +from .merchant_center_account_link import ( + CreateMerchantCenterAccountLinkMetadata, + MerchantCenterAccountLink, +) +from .merchant_center_account_link_service import ( + CreateMerchantCenterAccountLinkRequest, + DeleteMerchantCenterAccountLinkRequest, + ListMerchantCenterAccountLinksRequest, + ListMerchantCenterAccountLinksResponse, +) +from .model import ( + Model, +) +from .model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + GetModelRequest, + ListModelsRequest, + ListModelsResponse, + PauseModelRequest, + ResumeModelRequest, + TuneModelMetadata, + TuneModelRequest, + TuneModelResponse, + UpdateModelRequest, +) +from .prediction_service import ( + PredictRequest, + PredictResponse, +) +from .product import ( + Product, +) +from .product_service import ( + AddFulfillmentPlacesMetadata, + AddFulfillmentPlacesRequest, + AddFulfillmentPlacesResponse, + AddLocalInventoriesMetadata, + AddLocalInventoriesRequest, + AddLocalInventoriesResponse, + CreateProductRequest, + DeleteProductRequest, + GetProductRequest, + ListProductsRequest, + ListProductsResponse, + RemoveFulfillmentPlacesMetadata, + RemoveFulfillmentPlacesRequest, + RemoveFulfillmentPlacesResponse, + RemoveLocalInventoriesMetadata, + RemoveLocalInventoriesRequest, + RemoveLocalInventoriesResponse, + SetInventoryMetadata, + SetInventoryRequest, + SetInventoryResponse, + UpdateProductRequest, +) +from .promotion import ( + Promotion, +) +from .purge_config import ( + PurgeMetadata, + PurgeProductsMetadata, + PurgeProductsRequest, + PurgeProductsResponse, + PurgeUserEventsRequest, + PurgeUserEventsResponse, +) +from .search_service import ( + ExperimentInfo, + SearchRequest, + SearchResponse, +) +from .serving_config import ( + ServingConfig, +) +from .serving_config_service import ( + AddControlRequest, + CreateServingConfigRequest, + DeleteServingConfigRequest, + GetServingConfigRequest, + ListServingConfigsRequest, + ListServingConfigsResponse, + RemoveControlRequest, + UpdateServingConfigRequest, +) +from .user_event import ( + CompletionDetail, + ProductDetail, + PurchaseTransaction, + UserEvent, +) +from .user_event_service import ( + CollectUserEventRequest, + RejoinUserEventsMetadata, + RejoinUserEventsRequest, + RejoinUserEventsResponse, + WriteUserEventRequest, +) + +__all__ = ( + 'AttributesConfig', + 'Catalog', + 'CatalogAttribute', + 'CompletionConfig', + 'MerchantCenterFeedFilter', + 'MerchantCenterLink', + 'MerchantCenterLinkingConfig', + 'ProductLevelConfig', + 'AddCatalogAttributeRequest', + 'BatchRemoveCatalogAttributesRequest', + 'BatchRemoveCatalogAttributesResponse', + 'GetAttributesConfigRequest', + 'GetCompletionConfigRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'RemoveCatalogAttributeRequest', + 'ReplaceCatalogAttributeRequest', + 'SetDefaultBranchRequest', + 'UpdateAttributesConfigRequest', + 'UpdateCatalogRequest', + 'UpdateCompletionConfigRequest', + 'Audience', + 'ColorInfo', + 'Condition', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'LocalInventory', + 'PriceInfo', + 'Rating', + 'Rule', + 'UserInfo', + 'AttributeConfigLevel', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'SolutionType', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'Control', + 'CreateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + 'UpdateControlRequest', + 'BigQueryOutputResult', + 'ExportErrorsConfig', + 'ExportMetadata', + 'ExportProductsResponse', + 'ExportUserEventsResponse', + 'GcsOutputResult', + 'OutputResult', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'TransformedUserEventsMetadata', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'CreateMerchantCenterAccountLinkMetadata', + 'MerchantCenterAccountLink', + 'CreateMerchantCenterAccountLinkRequest', + 'DeleteMerchantCenterAccountLinkRequest', + 'ListMerchantCenterAccountLinksRequest', + 'ListMerchantCenterAccountLinksResponse', + 'Model', + 'CreateModelMetadata', + 'CreateModelRequest', + 'DeleteModelRequest', + 'GetModelRequest', + 'ListModelsRequest', + 'ListModelsResponse', + 'PauseModelRequest', + 'ResumeModelRequest', + 'TuneModelMetadata', + 'TuneModelRequest', + 'TuneModelResponse', + 'UpdateModelRequest', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'Promotion', + 'PurgeMetadata', + 'PurgeProductsMetadata', + 'PurgeProductsRequest', + 'PurgeProductsResponse', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'ExperimentInfo', + 'SearchRequest', + 'SearchResponse', + 'ServingConfig', + 'AddControlRequest', + 'CreateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'RemoveControlRequest', + 'UpdateServingConfigRequest', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog.py new file mode 100644 index 00000000..0282f872 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog.py @@ -0,0 +1,690 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'ProductLevelConfig', + 'CatalogAttribute', + 'AttributesConfig', + 'CompletionConfig', + 'MerchantCenterLink', + 'MerchantCenterFeedFilter', + 'MerchantCenterLinkingConfig', + 'Catalog', + }, +) + + +class ProductLevelConfig(proto.Message): + r"""Configures what level the product should be uploaded with + regards to how users will be send events and how predictions + will be made. + + Attributes: + ingestion_product_type (str): + The type of [Product][google.cloud.retail.v2alpha.Product]s + allowed to be ingested into the catalog. Acceptable values + are: + + - ``primary`` (default): You can ingest + [Product][google.cloud.retail.v2alpha.Product]s of all + types. When ingesting a + [Product][google.cloud.retail.v2alpha.Product], its type + will default to + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + if unset. + - ``variant`` (incompatible with Retail Search): You can + only ingest + [Product.Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s. This + means + [Product.primary_product_id][google.cloud.retail.v2alpha.Product.primary_product_id] + cannot be empty. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``variant`` and + [merchant_center_product_id_field][google.cloud.retail.v2alpha.ProductLevelConfig.merchant_center_product_id_field] + is ``itemGroupId``, an INVALID_ARGUMENT error is returned. + + See `Product + levels `__ + for more details. + merchant_center_product_id_field (str): + Which field of `Merchant Center + Product `__ + should be imported as + [Product.id][google.cloud.retail.v2alpha.Product.id]. + Acceptable values are: + + - ``offerId`` (default): Import ``offerId`` as the product + ID. + - ``itemGroupId``: Import ``itemGroupId`` as the product + ID. Notice that Retail API will choose one item from the + ones with the same ``itemGroupId``, and use it to + represent the item group. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``itemGroupId`` and + [ingestion_product_type][google.cloud.retail.v2alpha.ProductLevelConfig.ingestion_product_type] + is ``variant``, an INVALID_ARGUMENT error is returned. + + See `Product + levels `__ + for more details. + """ + + ingestion_product_type: str = proto.Field( + proto.STRING, + number=1, + ) + merchant_center_product_id_field: str = proto.Field( + proto.STRING, + number=2, + ) + + +class CatalogAttribute(proto.Message): + r"""Catalog level attribute config for an attribute. For example, + if customers want to enable/disable facet for a specific + attribute. + + Attributes: + key (str): + Required. Attribute name. For example: ``color``, + ``brands``, ``attributes.custom_attribute``, such as + ``attributes.xyz``. To be indexable, the attribute name can + contain only alpha-numeric characters and underscores. For + example, an attribute named ``attributes.abc_xyz`` can be + indexed, but an attribute named ``attributes.abc-xyz`` + cannot be indexed. + + If the attribute key starts with ``attributes.``, then the + attribute is a custom attribute. Attributes such as + ``brands``, ``patterns``, and ``title`` are built-in and + called system attributes. + in_use (bool): + Output only. Indicates whether this attribute has been used + by any products. ``True`` if at least one + [Product][google.cloud.retail.v2alpha.Product] is using this + attribute in + [Product.attributes][google.cloud.retail.v2alpha.Product.attributes]. + Otherwise, this field is ``False``. + + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + can be pre-loaded by using + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.AddCatalogAttribute], + [CatalogService.ImportCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.ImportCatalogAttributes], + or + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2alpha.CatalogService.UpdateAttributesConfig] + APIs. This field is ``False`` for pre-loaded + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute]s. + + Only pre-loaded [catalog + attributes][google.cloud.retail.v2alpha.CatalogAttribute] + that are neither in use by products nor predefined can be + deleted. [Catalog + attributes][google.cloud.retail.v2alpha.CatalogAttribute] + that are either in use by products or are predefined + attributes cannot be deleted; however, their configuration + properties will reset to default values upon removal + request. + + After catalog changes, it takes about 10 minutes for this + field to update. + type_ (google.cloud.retail_v2alpha.types.CatalogAttribute.AttributeType): + Output only. The type of this attribute. This is derived + from the attribute in + [Product.attributes][google.cloud.retail.v2alpha.Product.attributes]. + indexable_option (google.cloud.retail_v2alpha.types.CatalogAttribute.IndexableOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2alpha.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if INDEXABLE_ENABLED + attribute values are indexed so that it can be filtered, + faceted, or boosted in + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search]. + + Must be specified, otherwise throws INVALID_FORMAT error. + dynamic_facetable_option (google.cloud.retail_v2alpha.types.CatalogAttribute.DynamicFacetableOption): + If DYNAMIC_FACETABLE_ENABLED, attribute values are available + for dynamic facet. Could only be DYNAMIC_FACETABLE_DISABLED + if + [CatalogAttribute.indexable_option][google.cloud.retail.v2alpha.CatalogAttribute.indexable_option] + is INDEXABLE_DISABLED. Otherwise, an INVALID_ARGUMENT error + is returned. + + Must be specified, otherwise throws INVALID_FORMAT error. + searchable_option (google.cloud.retail_v2alpha.types.CatalogAttribute.SearchableOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2alpha.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if SEARCHABLE_ENABLED, + attribute values are searchable by text queries in + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search]. + + If SEARCHABLE_ENABLED but attribute type is numerical, + attribute values will not be searchable by text queries in + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search], + as there are no text values associated to numerical + attributes. + + Must be specified, otherwise throws INVALID_FORMAT error. + recommendations_filtering_option (google.cloud.retail_v2alpha.types.RecommendationsFilteringOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2alpha.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if + RECOMMENDATIONS_FILTERING_ENABLED, attribute values are + filterable for recommendations. This option works for + categorical features only, does not work for numerical + features, inventory filtering. + exact_searchable_option (google.cloud.retail_v2alpha.types.CatalogAttribute.ExactSearchableOption): + If EXACT_SEARCHABLE_ENABLED, attribute values will be exact + searchable. This property only applies to textual custom + attributes and requires indexable set to enabled to enable + exact-searchable. If unset, the server behavior defaults to + [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2alpha.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. + retrievable_option (google.cloud.retail_v2alpha.types.CatalogAttribute.RetrievableOption): + If RETRIEVABLE_ENABLED, attribute values are retrievable in + the search results. If unset, the server behavior defaults + to + [RETRIEVABLE_DISABLED][google.cloud.retail.v2alpha.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. + """ + class AttributeType(proto.Enum): + r"""The type of an attribute. + + Values: + UNKNOWN (0): + The type of the attribute is unknown. + + Used when type cannot be derived from attribute that is not + [in_use][google.cloud.retail.v2alpha.CatalogAttribute.in_use]. + TEXTUAL (1): + Textual attribute. + NUMERICAL (2): + Numerical attribute. + """ + UNKNOWN = 0 + TEXTUAL = 1 + NUMERICAL = 2 + + class IndexableOption(proto.Enum): + r"""The status of the indexable option of a catalog attribute. + + Values: + INDEXABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + INDEXABLE_ENABLED (1): + Indexable option enabled for an attribute. + INDEXABLE_DISABLED (2): + Indexable option disabled for an attribute. + """ + INDEXABLE_OPTION_UNSPECIFIED = 0 + INDEXABLE_ENABLED = 1 + INDEXABLE_DISABLED = 2 + + class DynamicFacetableOption(proto.Enum): + r"""The status of the dynamic facetable option of a catalog + attribute. + + Values: + DYNAMIC_FACETABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + DYNAMIC_FACETABLE_ENABLED (1): + Dynamic facetable option enabled for an + attribute. + DYNAMIC_FACETABLE_DISABLED (2): + Dynamic facetable option disabled for an + attribute. + """ + DYNAMIC_FACETABLE_OPTION_UNSPECIFIED = 0 + DYNAMIC_FACETABLE_ENABLED = 1 + DYNAMIC_FACETABLE_DISABLED = 2 + + class SearchableOption(proto.Enum): + r"""The status of the searchable option of a catalog attribute. + + Values: + SEARCHABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + SEARCHABLE_ENABLED (1): + Searchable option enabled for an attribute. + SEARCHABLE_DISABLED (2): + Searchable option disabled for an attribute. + """ + SEARCHABLE_OPTION_UNSPECIFIED = 0 + SEARCHABLE_ENABLED = 1 + SEARCHABLE_DISABLED = 2 + + class ExactSearchableOption(proto.Enum): + r"""The status of the exact-searchable option of a catalog + attribute. + + Values: + EXACT_SEARCHABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + EXACT_SEARCHABLE_ENABLED (1): + Exact searchable option enabled for an + attribute. + EXACT_SEARCHABLE_DISABLED (2): + Exact searchable option disabled for an + attribute. + """ + EXACT_SEARCHABLE_OPTION_UNSPECIFIED = 0 + EXACT_SEARCHABLE_ENABLED = 1 + EXACT_SEARCHABLE_DISABLED = 2 + + class RetrievableOption(proto.Enum): + r"""The status of the retrievable option of a catalog attribute. + + Values: + RETRIEVABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + RETRIEVABLE_ENABLED (1): + Retrievable option enabled for an attribute. + RETRIEVABLE_DISABLED (2): + Retrievable option disabled for an attribute. + """ + RETRIEVABLE_OPTION_UNSPECIFIED = 0 + RETRIEVABLE_ENABLED = 1 + RETRIEVABLE_DISABLED = 2 + + key: str = proto.Field( + proto.STRING, + number=1, + ) + in_use: bool = proto.Field( + proto.BOOL, + number=9, + ) + type_: AttributeType = proto.Field( + proto.ENUM, + number=10, + enum=AttributeType, + ) + indexable_option: IndexableOption = proto.Field( + proto.ENUM, + number=5, + enum=IndexableOption, + ) + dynamic_facetable_option: DynamicFacetableOption = proto.Field( + proto.ENUM, + number=6, + enum=DynamicFacetableOption, + ) + searchable_option: SearchableOption = proto.Field( + proto.ENUM, + number=7, + enum=SearchableOption, + ) + recommendations_filtering_option: common.RecommendationsFilteringOption = proto.Field( + proto.ENUM, + number=8, + enum=common.RecommendationsFilteringOption, + ) + exact_searchable_option: ExactSearchableOption = proto.Field( + proto.ENUM, + number=11, + enum=ExactSearchableOption, + ) + retrievable_option: RetrievableOption = proto.Field( + proto.ENUM, + number=12, + enum=RetrievableOption, + ) + + +class AttributesConfig(proto.Message): + r"""Catalog level attribute config. + + Attributes: + name (str): + Required. Immutable. The fully qualified resource name of + the attribute config. Format: + ``projects/*/locations/*/catalogs/*/attributesConfig`` + catalog_attributes (MutableMapping[str, google.cloud.retail_v2alpha.types.CatalogAttribute]): + Enable attribute(s) config at catalog level. For example, + indexable, dynamic_facetable, or searchable for each + attribute. + + The key is catalog attribute's name. For example: ``color``, + ``brands``, ``attributes.custom_attribute``, such as + ``attributes.xyz``. + + The maximum number of catalog attributes allowed in a + request is 1000. + attribute_config_level (google.cloud.retail_v2alpha.types.AttributeConfigLevel): + Output only. The + [AttributeConfigLevel][google.cloud.retail.v2alpha.AttributeConfigLevel] + used for this catalog. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attributes: MutableMapping[str, 'CatalogAttribute'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message='CatalogAttribute', + ) + attribute_config_level: common.AttributeConfigLevel = proto.Field( + proto.ENUM, + number=3, + enum=common.AttributeConfigLevel, + ) + + +class CompletionConfig(proto.Message): + r"""Catalog level autocomplete config for customers to customize + autocomplete feature's settings. + + Attributes: + name (str): + Required. Immutable. Fully qualified name + ``projects/*/locations/*/catalogs/*/completionConfig`` + matching_order (str): + Specifies the matching order for autocomplete suggestions, + e.g., a query consisting of 'sh' with 'out-of-order' + specified would suggest "women's shoes", whereas a query of + 'red s' with 'exact-prefix' specified would suggest "red + shoes". Currently supported values: + + - 'out-of-order' + - 'exact-prefix' + + Default value: 'exact-prefix'. + max_suggestions (int): + The maximum number of autocomplete + suggestions returned per term. Default value is + 20. If left unset or set to 0, then will + fallback to default value. + + Value range is 1 to 20. + min_prefix_length (int): + The minimum number of characters needed to be + typed in order to get suggestions. Default value + is 2. If left unset or set to 0, then will + fallback to default value. + + Value range is 1 to 20. + auto_learning (bool): + If set to true, the auto learning function is enabled. Auto + learning uses user data to generate suggestions using ML + techniques. Default value is false. Only after enabling auto + learning can users use ``cloud-retail`` data in + [CompleteQueryRequest][google.cloud.retail.v2alpha.CompleteQueryRequest]. + suggestions_input_config (google.cloud.retail_v2alpha.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete suggestion phrases. + last_suggestions_import_operation (str): + Output only. Name of the LRO corresponding to the latest + suggestion terms list import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + denylist_input_config (google.cloud.retail_v2alpha.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete denylist phrases. + last_denylist_import_operation (str): + Output only. Name of the LRO corresponding to the latest + denylist import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + allowlist_input_config (google.cloud.retail_v2alpha.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete allowlist phrases. + last_allowlist_import_operation (str): + Output only. Name of the LRO corresponding to the latest + allowlist import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + matching_order: str = proto.Field( + proto.STRING, + number=2, + ) + max_suggestions: int = proto.Field( + proto.INT32, + number=3, + ) + min_prefix_length: int = proto.Field( + proto.INT32, + number=4, + ) + auto_learning: bool = proto.Field( + proto.BOOL, + number=11, + ) + suggestions_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=5, + message=import_config.CompletionDataInputConfig, + ) + last_suggestions_import_operation: str = proto.Field( + proto.STRING, + number=6, + ) + denylist_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=7, + message=import_config.CompletionDataInputConfig, + ) + last_denylist_import_operation: str = proto.Field( + proto.STRING, + number=8, + ) + allowlist_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=9, + message=import_config.CompletionDataInputConfig, + ) + last_allowlist_import_operation: str = proto.Field( + proto.STRING, + number=10, + ) + + +class MerchantCenterLink(proto.Message): + r"""Represents a link between a Merchant Center account and a + branch. Once a link is established, products from the linked + merchant center account will be streamed to the linked branch. + + Attributes: + merchant_center_account_id (int): + Required. The linked `Merchant center account + ID `__. + The account must be a standalone account or a sub-account of + a MCA. + branch_id (str): + The branch ID (e.g. 0/1/2) within this catalog that products + from merchant_center_account_id are streamed to. When + updating this field, an empty value will use the currently + configured default branch. However, changing the default + branch later on won't change the linked branch here. + + A single branch ID can only have one linked merchant center + account ID. + destinations (MutableSequence[str]): + String representing the destination to import for, all if + left empty. List of possible values is given in `Included + destination `__. + List of allowed string values: "Shopping_ads", + "Buy_on_google_listings", "Display_ads", "Local_inventory + \_ads", "Free_listings", "Free_local_listings" NOTE: The + string values are case sensitive. + region_code (str): + Region code of offers to accept. 2-letter Uppercase ISO + 3166-1 alpha-2 code. List of values can be found + `here `__ + under the ``region`` tag. If left blank no region filtering + will be performed. + + Example value: ``US``. + language_code (str): + Language of the title/description and other string + attributes. Use language tags defined by `BCP + 47 `__. ISO + 639-1. + + This specifies the language of offers in Merchant Center + that will be accepted. If empty no language filtering will + be performed. + + Example value: ``en``. + feeds (MutableSequence[google.cloud.retail_v2alpha.types.MerchantCenterFeedFilter]): + Criteria for the Merchant Center feeds to be + ingested via the link. All offers will be + ingested if the list is empty. Otherwise the + offers will be ingested from selected feeds. + """ + + merchant_center_account_id: int = proto.Field( + proto.INT64, + number=1, + ) + branch_id: str = proto.Field( + proto.STRING, + number=2, + ) + destinations: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + region_code: str = proto.Field( + proto.STRING, + number=4, + ) + language_code: str = proto.Field( + proto.STRING, + number=5, + ) + feeds: MutableSequence['MerchantCenterFeedFilter'] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message='MerchantCenterFeedFilter', + ) + + +class MerchantCenterFeedFilter(proto.Message): + r"""Merchant Center Feed filter criterion. + + Attributes: + primary_feed_id (int): + Merchant Center primary feed ID. + primary_feed_name (str): + Merchant Center primary feed name. The name + is used for the display purposes only. + """ + + primary_feed_id: int = proto.Field( + proto.INT64, + number=1, + ) + primary_feed_name: str = proto.Field( + proto.STRING, + number=2, + ) + + +class MerchantCenterLinkingConfig(proto.Message): + r"""Configures Merchant Center linking. + Links contained in the config will be used to sync data from a + Merchant Center account to a Cloud Retail branch. + + Attributes: + links (MutableSequence[google.cloud.retail_v2alpha.types.MerchantCenterLink]): + Links between Merchant Center accounts and + branches. + """ + + links: MutableSequence['MerchantCenterLink'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='MerchantCenterLink', + ) + + +class Catalog(proto.Message): + r"""The catalog configuration. + + Attributes: + name (str): + Required. Immutable. The fully qualified + resource name of the catalog. + display_name (str): + Required. Immutable. The catalog display name. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + product_level_config (google.cloud.retail_v2alpha.types.ProductLevelConfig): + Required. The product level configuration. + merchant_center_linking_config (google.cloud.retail_v2alpha.types.MerchantCenterLinkingConfig): + The Merchant Center linking configuration. + Once a link is added, the data stream from + Merchant Center to Cloud Retail will be enabled + automatically. The requester must have access to + the merchant center account in order to make + changes to this field. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + product_level_config: 'ProductLevelConfig' = proto.Field( + proto.MESSAGE, + number=4, + message='ProductLevelConfig', + ) + merchant_center_linking_config: 'MerchantCenterLinkingConfig' = proto.Field( + proto.MESSAGE, + number=6, + message='MerchantCenterLinkingConfig', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog_service.py new file mode 100644 index 00000000..e1105d1f --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/catalog_service.py @@ -0,0 +1,518 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import catalog as gcr_catalog +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'UpdateCatalogRequest', + 'SetDefaultBranchRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'GetCompletionConfigRequest', + 'UpdateCompletionConfigRequest', + 'GetAttributesConfigRequest', + 'UpdateAttributesConfigRequest', + 'AddCatalogAttributeRequest', + 'RemoveCatalogAttributeRequest', + 'BatchRemoveCatalogAttributesRequest', + 'BatchRemoveCatalogAttributesResponse', + 'ReplaceCatalogAttributeRequest', + }, +) + + +class ListCatalogsRequest(proto.Message): + r"""Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + method. + + Attributes: + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2alpha.Catalog]s under this + location, regardless of whether or not this location exists, + a PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of + [Catalog][google.cloud.retail.v2alpha.Catalog]s to return. + If unspecified, defaults to 50. The maximum allowed value is + 1000. Values above 1000 will be coerced to 1000. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [ListCatalogsResponse.next_page_token][google.cloud.retail.v2alpha.ListCatalogsResponse.next_page_token], + received from a previous + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + """ + + 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 ListCatalogsResponse(proto.Message): + r"""Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2alpha.CatalogService.ListCatalogs] + method. + + Attributes: + catalogs (MutableSequence[google.cloud.retail_v2alpha.types.Catalog]): + All the customer's + [Catalog][google.cloud.retail.v2alpha.Catalog]s. + next_page_token (str): + A token that can be sent as + [ListCatalogsRequest.page_token][google.cloud.retail.v2alpha.ListCatalogsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + catalogs: MutableSequence[gcr_catalog.Catalog] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class UpdateCatalogRequest(proto.Message): + r"""Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2alpha.CatalogService.UpdateCatalog] + method. + + Attributes: + catalog (google.cloud.retail_v2alpha.types.Catalog): + Required. The [Catalog][google.cloud.retail.v2alpha.Catalog] + to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2alpha.Catalog], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2alpha.Catalog] to + update does not exist, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2alpha.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + """ + + catalog: gcr_catalog.Catalog = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class SetDefaultBranchRequest(proto.Message): + r"""Request message to set a specified branch as new default_branch. + + Attributes: + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + branch_id (str): + The final component of the resource name of a branch. + + This field must be one of "0", "1" or "2". Otherwise, an + INVALID_ARGUMENT error is returned. + + If there are no sufficient active products in the targeted + branch and + [force][google.cloud.retail.v2alpha.SetDefaultBranchRequest.force] + is not set, a FAILED_PRECONDITION error is returned. + note (str): + Some note on this request, this can be retrieved by + [CatalogService.GetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.GetDefaultBranch] + before next valid default branch set occurs. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + force (bool): + If set to true, it permits switching to a branch with + [branch_id][google.cloud.retail.v2alpha.SetDefaultBranchRequest.branch_id] + even if it has no sufficient active products. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + branch_id: str = proto.Field( + proto.STRING, + number=2, + ) + note: str = proto.Field( + proto.STRING, + number=3, + ) + force: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class GetDefaultBranchRequest(proto.Message): + r"""Request message to show which branch is currently the default + branch. + + Attributes: + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetDefaultBranchResponse(proto.Message): + r"""Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2alpha.CatalogService.GetDefaultBranch]. + + Attributes: + branch (str): + Full resource name of the branch id currently + set as default branch. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when this branch is set to default. + note (str): + This corresponds to + [SetDefaultBranchRequest.note][google.cloud.retail.v2alpha.SetDefaultBranchRequest.note] + field, when this branch was set as default. + """ + + branch: str = proto.Field( + proto.STRING, + number=1, + ) + set_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + note: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetCompletionConfigRequest(proto.Message): + r"""Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2alpha.CatalogService.GetCompletionConfig] + method. + + Attributes: + name (str): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateCompletionConfigRequest(proto.Message): + r"""Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2alpha.CatalogService.UpdateCompletionConfig] + method. + + Attributes: + completion_config (google.cloud.retail_v2alpha.types.CompletionConfig): + Required. The + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2alpha.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2alpha.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2alpha.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2alpha.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2alpha.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + """ + + completion_config: gcr_catalog.CompletionConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.CompletionConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetAttributesConfigRequest(proto.Message): + r"""Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2alpha.CatalogService.GetAttributesConfig] + method. + + Attributes: + name (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateAttributesConfigRequest(proto.Message): + r"""Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2alpha.CatalogService.UpdateAttributesConfig] + method. + + Attributes: + attributes_config (google.cloud.retail_v2alpha.types.AttributesConfig): + Required. The + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2alpha.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2alpha.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + """ + + attributes_config: gcr_catalog.AttributesConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.AttributesConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class AddCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.AddCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + catalog_attribute (google.cloud.retail_v2alpha.types.CatalogAttribute): + Required. The + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to add. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attribute: gcr_catalog.CatalogAttribute = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_catalog.CatalogAttribute, + ) + + +class RemoveCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.RemoveCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + key (str): + Required. The attribute name key of the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to remove. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + key: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BatchRemoveCatalogAttributesRequest(proto.Message): + r"""Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes] + method. + + Attributes: + attributes_config (str): + Required. The attributes config resource shared by all + catalog attributes being deleted. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + attribute_keys (MutableSequence[str]): + Required. The attribute name keys of the + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute]s + to delete. A maximum of 1000 catalog attributes can be + deleted in a batch. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + attribute_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchRemoveCatalogAttributesResponse(proto.Message): + r"""Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes]. + + Attributes: + deleted_catalog_attributes (MutableSequence[str]): + Catalog attributes that were deleted. Only pre-loaded + [catalog + attributes][google.cloud.retail.v2alpha.CatalogAttribute] + that are neither [in + use][google.cloud.retail.v2alpha.CatalogAttribute.in_use] by + products nor predefined can be deleted. + reset_catalog_attributes (MutableSequence[str]): + Catalog attributes that were reset. [Catalog + attributes][google.cloud.retail.v2alpha.CatalogAttribute] + that are either [in + use][google.cloud.retail.v2alpha.CatalogAttribute.in_use] by + products or are predefined attributes cannot be deleted; + however, their configuration properties will reset to + default values upon removal request. + """ + + deleted_catalog_attributes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + reset_catalog_attributes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class ReplaceCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2alpha.CatalogService.ReplaceCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + catalog_attribute (google.cloud.retail_v2alpha.types.CatalogAttribute): + Required. The updated + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute]. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + to update. The following are NOT supported: + + - [CatalogAttribute.key][google.cloud.retail.v2alpha.CatalogAttribute.key] + + If not set, all supported fields are updated. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attribute: gcr_catalog.CatalogAttribute = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_catalog.CatalogAttribute, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=3, + message=field_mask_pb2.FieldMask, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/common.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/common.py new file mode 100644 index 00000000..d060893e --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/common.py @@ -0,0 +1,1262 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'AttributeConfigLevel', + 'SolutionType', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'Condition', + 'Rule', + 'Audience', + 'ColorInfo', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'PriceInfo', + 'Rating', + 'UserInfo', + 'LocalInventory', + }, +) + + +class AttributeConfigLevel(proto.Enum): + r"""At which level we offer configuration for attributes. + + Values: + ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED (0): + Value used when unset. In this case, server behavior + defaults to + [CATALOG_LEVEL_ATTRIBUTE_CONFIG][google.cloud.retail.v2alpha.AttributeConfigLevel.CATALOG_LEVEL_ATTRIBUTE_CONFIG]. + PRODUCT_LEVEL_ATTRIBUTE_CONFIG (1): + At this level, we honor the attribute configurations set in + [Product.attributes][google.cloud.retail.v2alpha.Product.attributes]. + CATALOG_LEVEL_ATTRIBUTE_CONFIG (2): + At this level, we honor the attribute configurations set in + [CatalogConfig.attribute_configs][google.cloud.retail.v2alpha.CatalogConfig.attribute_configs]. + """ + ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED = 0 + PRODUCT_LEVEL_ATTRIBUTE_CONFIG = 1 + CATALOG_LEVEL_ATTRIBUTE_CONFIG = 2 + + +class SolutionType(proto.Enum): + r"""The type of solution. + + Values: + SOLUTION_TYPE_UNSPECIFIED (0): + Default value. + SOLUTION_TYPE_RECOMMENDATION (1): + Used for Recommendations AI. + SOLUTION_TYPE_SEARCH (2): + Used for Retail Search. + """ + SOLUTION_TYPE_UNSPECIFIED = 0 + SOLUTION_TYPE_RECOMMENDATION = 1 + SOLUTION_TYPE_SEARCH = 2 + + +class RecommendationsFilteringOption(proto.Enum): + r"""If filtering for recommendations is enabled. + + Values: + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED (0): + Value used when unset. In this case, server behavior + defaults to + [RECOMMENDATIONS_FILTERING_DISABLED][google.cloud.retail.v2alpha.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED]. + RECOMMENDATIONS_FILTERING_DISABLED (1): + Recommendation filtering is disabled. + RECOMMENDATIONS_FILTERING_ENABLED (3): + Recommendation filtering is enabled. + """ + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED = 0 + RECOMMENDATIONS_FILTERING_DISABLED = 1 + RECOMMENDATIONS_FILTERING_ENABLED = 3 + + +class SearchSolutionUseCase(proto.Enum): + r"""The use case of Cloud Retail Search. + + Values: + SEARCH_SOLUTION_USE_CASE_UNSPECIFIED (0): + The value when it's unspecified. In this case, server + behavior defaults to + [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2alpha.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH]. + SEARCH_SOLUTION_USE_CASE_SEARCH (1): + Search use case. Expects the traffic has a non-empty + [query][google.cloud.retail.v2alpha.SearchRequest.query]. + SEARCH_SOLUTION_USE_CASE_BROWSE (2): + Browse use case. Expects the traffic has an empty + [query][google.cloud.retail.v2alpha.SearchRequest.query]. + """ + SEARCH_SOLUTION_USE_CASE_UNSPECIFIED = 0 + SEARCH_SOLUTION_USE_CASE_SEARCH = 1 + SEARCH_SOLUTION_USE_CASE_BROWSE = 2 + + +class Condition(proto.Message): + r"""Metadata that is used to define a condition that triggers an action. + A valid condition must specify at least one of 'query_terms' or + 'products_filter'. If multiple fields are specified, the condition + is met if all the fields are satisfied e.g. if a set of query terms + and product_filter are set, then only items matching the + product_filter for requests with a query matching the query terms + wil get boosted. + + Attributes: + query_terms (MutableSequence[google.cloud.retail_v2alpha.types.Condition.QueryTerm]): + A list (up to 10 entries) of terms to match + the query on. If not specified, match all + queries. If many query terms are specified, the + condition is matched if any of the terms is a + match (i.e. using the OR operator). + active_time_range (MutableSequence[google.cloud.retail_v2alpha.types.Condition.TimeRange]): + Range of time(s) specifying when Condition is + active. Condition true if any time range + matches. + """ + + class QueryTerm(proto.Message): + r"""Query terms that we want to match on. + + Attributes: + value (str): + The value of the term to match on. + Value cannot be empty. + Value can have at most 3 terms if specified as a + partial match. Each space separated string is + considered as one term. For example, "a b c" is + 3 terms and allowed, but " a b c d" is 4 terms + and not allowed for a partial match. + full_match (bool): + Whether this is supposed to be a full or + partial match. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + ) + full_match: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TimeRange(proto.Message): + r"""Used for time-dependent conditions. + Example: Want to have rule applied for week long sale. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Start of time range. Range is inclusive. + end_time (google.protobuf.timestamp_pb2.Timestamp): + End of time range. Range is inclusive. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + query_terms: MutableSequence[QueryTerm] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=QueryTerm, + ) + active_time_range: MutableSequence[TimeRange] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=TimeRange, + ) + + +class Rule(proto.Message): + r"""A rule is a condition-action pair + + - A condition defines when a rule is to be triggered. + - An action specifies what occurs on that trigger. Currently rules + only work for [controls][google.cloud.retail.v2alpha.Control] + with + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2alpha.SolutionType.SOLUTION_TYPE_SEARCH]. + + 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: + boost_action (google.cloud.retail_v2alpha.types.Rule.BoostAction): + A boost action. + + This field is a member of `oneof`_ ``action``. + redirect_action (google.cloud.retail_v2alpha.types.Rule.RedirectAction): + Redirects a shopper to a specific page. + + This field is a member of `oneof`_ ``action``. + oneway_synonyms_action (google.cloud.retail_v2alpha.types.Rule.OnewaySynonymsAction): + Treats specific term as a synonym with a + group of terms. Group of terms will not be + treated as synonyms with the specific term. + + This field is a member of `oneof`_ ``action``. + do_not_associate_action (google.cloud.retail_v2alpha.types.Rule.DoNotAssociateAction): + Prevents term from being associated with + other terms. + + This field is a member of `oneof`_ ``action``. + replacement_action (google.cloud.retail_v2alpha.types.Rule.ReplacementAction): + Replaces specific terms in the query. + + This field is a member of `oneof`_ ``action``. + ignore_action (google.cloud.retail_v2alpha.types.Rule.IgnoreAction): + Ignores specific terms from query during + search. + + This field is a member of `oneof`_ ``action``. + filter_action (google.cloud.retail_v2alpha.types.Rule.FilterAction): + Filters results. + + This field is a member of `oneof`_ ``action``. + twoway_synonyms_action (google.cloud.retail_v2alpha.types.Rule.TwowaySynonymsAction): + Treats a set of terms as synonyms of one + another. + + This field is a member of `oneof`_ ``action``. + condition (google.cloud.retail_v2alpha.types.Condition): + Required. The condition that triggers the + rule. If the condition is empty, the rule will + always apply. + """ + + class BoostAction(proto.Message): + r"""A boost action to apply to results matching condition + specified above. + + Attributes: + boost (float): + Strength of the condition boost, which must be in [-1, 1]. + Negative boost means demotion. Default is 0.0. + + Setting to 1.0 gives the item a big promotion. However, it + does not necessarily mean that the boosted item will be the + top result at all times, nor that other items will be + excluded. Results could still be shown even when none of + them matches the condition. And results that are + significantly more relevant to the search query can still + trump your heavily favored but irrelevant items. + + Setting to -1.0 gives the item a big demotion. However, + results that are deeply relevant might still be shown. The + item will have an upstream battle to get a fairly high + ranking, but it is not blocked out completely. + + Setting to 0.0 means no boost applied. The boosting + condition is ignored. + products_filter (str): + The filter can have a max size of 5000 characters. An + expression which specifies which products to apply an action + to. The syntax and supported fields are the same as a filter + expression. See + [SearchRequest.filter][google.cloud.retail.v2alpha.SearchRequest.filter] + for detail syntax and limitations. + + Examples: + + - To boost products with product ID "product_1" or + "product_2", and color "Red" or "Blue": *(id: + ANY("product_1", "product_2"))* *AND* *(colorFamilies: + ANY("Red", "Blue"))* + """ + + boost: float = proto.Field( + proto.FLOAT, + number=1, + ) + products_filter: str = proto.Field( + proto.STRING, + number=2, + ) + + class FilterAction(proto.Message): + r"""- Rule Condition: + + - No + [Condition.query_terms][google.cloud.retail.v2alpha.Condition.query_terms] + provided is a global match. + - 1 or more + [Condition.query_terms][google.cloud.retail.v2alpha.Condition.query_terms] + provided are combined with OR operator. + + - Action Input: The request query and filter that are applied to + the retrieved products, in addition to any filters already + provided with the SearchRequest. The AND operator is used to + combine the query's existing filters with the filter rule(s). + NOTE: May result in 0 results when filters conflict. + - Action Result: Filters the returned objects to be ONLY those that + passed the filter. + + Attributes: + filter (str): + A filter to apply on the matching condition results. + Supported features: + + - [filter][google.cloud.retail.v2alpha.Rule.FilterAction.filter] + must be set. + - Filter syntax is identical to + [SearchRequest.filter][google.cloud.retail.v2alpha.SearchRequest.filter]. + See more details at the Retail Search `user + guide `__. + - To filter products with product ID "product_1" or + "product_2", and color "Red" or "Blue": *(id: + ANY("product_1", "product_2"))* *AND* *(colorFamilies: + ANY("Red", "Blue"))* + """ + + filter: str = proto.Field( + proto.STRING, + number=1, + ) + + class RedirectAction(proto.Message): + r"""Redirects a shopper to a specific page. + + - Rule Condition: + + - Must specify + [Condition.query_terms][google.cloud.retail.v2alpha.Condition.query_terms]. + + - Action Input: Request Query + - Action Result: Redirects shopper to provided uri. + + Attributes: + redirect_uri (str): + URL must have length equal or less than 2000 + characters. + """ + + redirect_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + class TwowaySynonymsAction(proto.Message): + r"""Creates a set of terms that will be treated as synonyms of each + other. Example: synonyms of "sneakers" and "shoes": + + - "sneakers" will use a synonym of "shoes". + - "shoes" will use a synonym of "sneakers". + + Attributes: + synonyms (MutableSequence[str]): + Defines a set of synonyms. + Can specify up to 100 synonyms. + Must specify at least 2 synonyms. + """ + + synonyms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class OnewaySynonymsAction(proto.Message): + r"""Maps a set of terms to a set of synonyms. Set of synonyms will be + treated as synonyms of each query term only. ``query_terms`` will + not be treated as synonyms of each other. Example: "sneakers" will + use a synonym of "shoes". "shoes" will not use a synonym of + "sneakers". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. + Will treat synonyms as their synonyms. + Not themselves synonyms of the synonyms. + Can specify up to 100 terms. + synonyms (MutableSequence[str]): + Defines a set of synonyms. + Cannot contain duplicates. + Can specify up to 100 synonyms. + oneway_terms (MutableSequence[str]): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + synonyms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + oneway_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + class DoNotAssociateAction(proto.Message): + r"""Prevents ``query_term`` from being associated with specified terms + during search. Example: Don't associate "gShoe" and "cheap". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. Will not consider + do_not_associate_terms for search if in search query. Can + specify up to 100 terms. + do_not_associate_terms (MutableSequence[str]): + Cannot contain duplicates or the query term. + Can specify up to 100 terms. + terms (MutableSequence[str]): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + do_not_associate_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class ReplacementAction(proto.Message): + r"""Replaces a term in the query. Multiple replacement candidates can be + specified. All ``query_terms`` will be replaced with the replacement + term. Example: Replace "gShoe" with "google shoe". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. + Will be replaced by replacement term. + Can specify up to 100 terms. + replacement_term (str): + Term that will be used for replacement. + term (str): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + replacement_term: str = proto.Field( + proto.STRING, + number=3, + ) + term: str = proto.Field( + proto.STRING, + number=1, + ) + + class IgnoreAction(proto.Message): + r"""Prevents a term in the query from being used in search. + Example: Don't search for "shoddy". + + Attributes: + ignore_terms (MutableSequence[str]): + Terms to ignore in the search query. + """ + + ignore_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + boost_action: BoostAction = proto.Field( + proto.MESSAGE, + number=2, + oneof='action', + message=BoostAction, + ) + redirect_action: RedirectAction = proto.Field( + proto.MESSAGE, + number=3, + oneof='action', + message=RedirectAction, + ) + oneway_synonyms_action: OnewaySynonymsAction = proto.Field( + proto.MESSAGE, + number=6, + oneof='action', + message=OnewaySynonymsAction, + ) + do_not_associate_action: DoNotAssociateAction = proto.Field( + proto.MESSAGE, + number=7, + oneof='action', + message=DoNotAssociateAction, + ) + replacement_action: ReplacementAction = proto.Field( + proto.MESSAGE, + number=8, + oneof='action', + message=ReplacementAction, + ) + ignore_action: IgnoreAction = proto.Field( + proto.MESSAGE, + number=9, + oneof='action', + message=IgnoreAction, + ) + filter_action: FilterAction = proto.Field( + proto.MESSAGE, + number=10, + oneof='action', + message=FilterAction, + ) + twoway_synonyms_action: TwowaySynonymsAction = proto.Field( + proto.MESSAGE, + number=11, + oneof='action', + message=TwowaySynonymsAction, + ) + condition: 'Condition' = proto.Field( + proto.MESSAGE, + number=1, + message='Condition', + ) + + +class Audience(proto.Message): + r"""An intended audience of the + [Product][google.cloud.retail.v2alpha.Product] for whom it's sold. + + Attributes: + genders (MutableSequence[str]): + The genders of the audience. Strongly encouraged to use the + standard values: "male", "female", "unisex". + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `gender `__. + Schema.org property + `Product.audience.suggestedGender `__. + age_groups (MutableSequence[str]): + The age groups of the audience. Strongly encouraged to use + the standard values: "newborn" (up to 3 months old), + "infant" (3–12 months old), "toddler" (1–5 years old), + "kids" (5–13 years old), "adult" (typically teens or older). + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `age_group `__. + Schema.org property + `Product.audience.suggestedMinAge `__ + and + `Product.audience.suggestedMaxAge `__. + """ + + genders: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + age_groups: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class ColorInfo(proto.Message): + r"""The color information of a + [Product][google.cloud.retail.v2alpha.Product]. + + Attributes: + color_families (MutableSequence[str]): + The standard color families. Strongly recommended to use the + following standard color groups: "Red", "Pink", "Orange", + "Yellow", "Purple", "Green", "Cyan", "Blue", "Brown", + "White", "Gray", "Black" and "Mixed". Normally it is + expected to have only 1 color family. May consider using + single "Mixed" instead of multiple values. + + A maximum of 5 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + colors (MutableSequence[str]): + The color display names, which may be different from + standard color family names, such as the color aliases used + in the website frontend. Normally it is expected to have + only 1 color. May consider using single "Mixed" instead of + multiple values. + + A maximum of 75 colors are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + """ + + color_families: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + colors: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class CustomAttribute(proto.Message): + r"""A custom attribute that is not explicitly modeled in + [Product][google.cloud.retail.v2alpha.Product]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text (MutableSequence[str]): + The textual values of this custom attribute. For example, + ``["yellow", "green"]`` when the key is "color". + + Empty string is not allowed. Otherwise, an INVALID_ARGUMENT + error is returned. + + Exactly one of + [text][google.cloud.retail.v2alpha.CustomAttribute.text] or + [numbers][google.cloud.retail.v2alpha.CustomAttribute.numbers] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. + numbers (MutableSequence[float]): + The numerical values of this custom attribute. For example, + ``[2.3, 15.4]`` when the key is "lengths_cm". + + Exactly one of + [text][google.cloud.retail.v2alpha.CustomAttribute.text] or + [numbers][google.cloud.retail.v2alpha.CustomAttribute.numbers] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. + searchable (bool): + This field is normally ignored unless + [AttributesConfig.attribute_config_level][google.cloud.retail.v2alpha.AttributesConfig.attribute_config_level] + of the [Catalog][google.cloud.retail.v2alpha.Catalog] is set + to the deprecated 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For + information about product-level attribute configuration, see + `Configuration + modes `__. + If true, custom attribute values are searchable by text + queries in + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2alpha.UserEvent]. + + Only set if type + [text][google.cloud.retail.v2alpha.CustomAttribute.text] is + set. Otherwise, a INVALID_ARGUMENT error is returned. + + This field is a member of `oneof`_ ``_searchable``. + indexable (bool): + This field is normally ignored unless + [AttributesConfig.attribute_config_level][google.cloud.retail.v2alpha.AttributesConfig.attribute_config_level] + of the [Catalog][google.cloud.retail.v2alpha.Catalog] is set + to the deprecated 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For + information about product-level attribute configuration, see + `Configuration + modes `__. + If true, custom attribute values are indexed, so that they + can be filtered, faceted or boosted in + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2alpha.UserEvent]. + + See + [SearchRequest.filter][google.cloud.retail.v2alpha.SearchRequest.filter], + [SearchRequest.facet_specs][google.cloud.retail.v2alpha.SearchRequest.facet_specs] + and + [SearchRequest.boost_spec][google.cloud.retail.v2alpha.SearchRequest.boost_spec] + for more details. + + This field is a member of `oneof`_ ``_indexable``. + """ + + text: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + numbers: MutableSequence[float] = proto.RepeatedField( + proto.DOUBLE, + number=2, + ) + searchable: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + indexable: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) + + +class FulfillmentInfo(proto.Message): + r"""Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + Attributes: + type_ (str): + The fulfillment type, including commonly used types (such as + pickup in store and same day delivery), and custom types. + Customers have to map custom types to their display names + before rendering UI. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + place_ids (MutableSequence[str]): + The IDs for this + [type][google.cloud.retail.v2alpha.FulfillmentInfo.type], + such as the store IDs for + [FulfillmentInfo.type.pickup-in-store][google.cloud.retail.v2alpha.FulfillmentInfo.type] + or the region IDs for + [FulfillmentInfo.type.same-day-delivery][google.cloud.retail.v2alpha.FulfillmentInfo.type]. + + A maximum of 3000 values are allowed. Each value must be a + string with a length limit of 30 characters, matching the + pattern ``[a-zA-Z0-9_-]+``, such as "store1" or "REGION-2". + Otherwise, an INVALID_ARGUMENT error is returned. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""[Product][google.cloud.retail.v2alpha.Product] image. + Recommendations AI and Retail Search do not use product images to + improve prediction and search results. However, product images can + be returned in results, and are shown in prediction or search + previews in the console. + + Attributes: + uri (str): + Required. URI of the image. + + This field must be a valid UTF-8 encoded URI with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + height (int): + Height of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + width (int): + Width of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + height: int = proto.Field( + proto.INT32, + number=2, + ) + width: int = proto.Field( + proto.INT32, + number=3, + ) + + +class Interval(proto.Message): + r"""A floating point interval. + + 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: + minimum (float): + Inclusive lower bound. + + This field is a member of `oneof`_ ``min``. + exclusive_minimum (float): + Exclusive lower bound. + + This field is a member of `oneof`_ ``min``. + maximum (float): + Inclusive upper bound. + + This field is a member of `oneof`_ ``max``. + exclusive_maximum (float): + Exclusive upper bound. + + This field is a member of `oneof`_ ``max``. + """ + + minimum: float = proto.Field( + proto.DOUBLE, + number=1, + oneof='min', + ) + exclusive_minimum: float = proto.Field( + proto.DOUBLE, + number=2, + oneof='min', + ) + maximum: float = proto.Field( + proto.DOUBLE, + number=3, + oneof='max', + ) + exclusive_maximum: float = proto.Field( + proto.DOUBLE, + number=4, + oneof='max', + ) + + +class PriceInfo(proto.Message): + r"""The price information of a + [Product][google.cloud.retail.v2alpha.Product]. + + Attributes: + currency_code (str): + The 3-letter currency code defined in `ISO + 4217 `__. + + If this field is an unrecognizable currency code, an + INVALID_ARGUMENT error is returned. + + The + [Product.Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s with the + same + [Product.primary_product_id][google.cloud.retail.v2alpha.Product.primary_product_id] + must share the same + [currency_code][google.cloud.retail.v2alpha.PriceInfo.currency_code]. + Otherwise, a FAILED_PRECONDITION error is returned. + price (float): + Price of the product. + + Google Merchant Center property + `price `__. + Schema.org property + `Offer.price `__. + original_price (float): + Price of the product without any discount. If zero, by + default set to be the + [price][google.cloud.retail.v2alpha.PriceInfo.price]. If + set, + [original_price][google.cloud.retail.v2alpha.PriceInfo.original_price] + should be greater than or equal to + [price][google.cloud.retail.v2alpha.PriceInfo.price], + otherwise an INVALID_ARGUMENT error is thrown. + cost (float): + The costs associated with the sale of a particular product. + Used for gross profit reporting. + + - Profit = + [price][google.cloud.retail.v2alpha.PriceInfo.price] - + [cost][google.cloud.retail.v2alpha.PriceInfo.cost] + + Google Merchant Center property + `cost_of_goods_sold `__. + price_effective_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2alpha.PriceInfo.price] starts + to be effective. This can be set as a future timestamp, and + the [price][google.cloud.retail.v2alpha.PriceInfo.price] is + only used for search after + [price_effective_time][google.cloud.retail.v2alpha.PriceInfo.price_effective_time]. + If so, the + [original_price][google.cloud.retail.v2alpha.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2alpha.PriceInfo.original_price] + is used before + [price_effective_time][google.cloud.retail.v2alpha.PriceInfo.price_effective_time]. + + Do not set if + [price][google.cloud.retail.v2alpha.PriceInfo.price] is + always effective because it will cause additional latency + during search. + price_expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2alpha.PriceInfo.price] stops + to be effective. The + [price][google.cloud.retail.v2alpha.PriceInfo.price] is used + for search before + [price_expire_time][google.cloud.retail.v2alpha.PriceInfo.price_expire_time]. + If this field is set, the + [original_price][google.cloud.retail.v2alpha.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2alpha.PriceInfo.original_price] + is used after + [price_expire_time][google.cloud.retail.v2alpha.PriceInfo.price_expire_time]. + + Do not set if + [price][google.cloud.retail.v2alpha.PriceInfo.price] is + always effective because it will cause additional latency + during search. + price_range (google.cloud.retail_v2alpha.types.PriceInfo.PriceRange): + Output only. The price range of all the child + [Product.Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s grouped + together on the + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]. Only + populated for + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct]. + Do not set this field in API requests. + """ + + class PriceRange(proto.Message): + r"""The price range of all + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product] having the same + [Product.primary_product_id][google.cloud.retail.v2alpha.Product.primary_product_id]. + + Attributes: + price (google.cloud.retail_v2alpha.types.Interval): + The inclusive + [Product.pricing_info.price][google.cloud.retail.v2alpha.PriceInfo.price] + interval of all + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product] having the + same + [Product.primary_product_id][google.cloud.retail.v2alpha.Product.primary_product_id]. + original_price (google.cloud.retail_v2alpha.types.Interval): + The inclusive + [Product.pricing_info.original_price][google.cloud.retail.v2alpha.PriceInfo.original_price] + internal of all + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product] having the + same + [Product.primary_product_id][google.cloud.retail.v2alpha.Product.primary_product_id]. + """ + + price: 'Interval' = proto.Field( + proto.MESSAGE, + number=1, + message='Interval', + ) + original_price: 'Interval' = proto.Field( + proto.MESSAGE, + number=2, + message='Interval', + ) + + currency_code: str = proto.Field( + proto.STRING, + number=1, + ) + price: float = proto.Field( + proto.FLOAT, + number=2, + ) + original_price: float = proto.Field( + proto.FLOAT, + number=3, + ) + cost: float = proto.Field( + proto.FLOAT, + number=4, + ) + price_effective_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + price_expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + price_range: PriceRange = proto.Field( + proto.MESSAGE, + number=7, + message=PriceRange, + ) + + +class Rating(proto.Message): + r"""The rating of a [Product][google.cloud.retail.v2alpha.Product]. + + Attributes: + rating_count (int): + The total number of ratings. This value is independent of + the value of + [rating_histogram][google.cloud.retail.v2alpha.Rating.rating_histogram]. + + This value must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + average_rating (float): + The average rating of the + [Product][google.cloud.retail.v2alpha.Product]. + + The rating is scaled at 1-5. Otherwise, an INVALID_ARGUMENT + error is returned. + rating_histogram (MutableSequence[int]): + List of rating counts per rating value (index = rating - 1). + The list is empty if there is no rating. If the list is + non-empty, its size is always 5. Otherwise, an + INVALID_ARGUMENT error is returned. + + For example, [41, 14, 13, 47, 303]. It means that the + [Product][google.cloud.retail.v2alpha.Product] got 41 + ratings with 1 star, 14 ratings with 2 star, and so on. + """ + + rating_count: int = proto.Field( + proto.INT32, + number=1, + ) + average_rating: float = proto.Field( + proto.FLOAT, + number=2, + ) + rating_histogram: MutableSequence[int] = proto.RepeatedField( + proto.INT32, + number=3, + ) + + +class UserInfo(proto.Message): + r"""Information of an end user. + + Attributes: + user_id (str): + Highly recommended for logged-in users. Unique identifier + for logged-in user, such as a user name. Don't set for + anonymous users. + + Always use a hashed value for this ID. + + Don't set the field to the same fixed ID for different + users. This mixes the event history of those users together, + which results in degraded model quality. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + ip_address (str): + The end user's IP address. This field is used to extract + location information for personalization. + + This field must be either an IPv4 address (e.g. + "104.133.9.80") or an IPv6 address (e.g. + "2001:0db8:85a3:0000:0000:8a2e:0370:7334"). Otherwise, an + INVALID_ARGUMENT error is returned. + + This should not be set when: + + - setting + [SearchRequest.user_info][google.cloud.retail.v2alpha.SearchRequest.user_info]. + - using the JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2alpha.UserEventService.CollectUserEvent] + or if + [direct_user_request][google.cloud.retail.v2alpha.UserInfo.direct_user_request] + is set. + user_agent (str): + User agent as included in the HTTP header. Required for + getting + [SearchResponse.sponsored_results][google.cloud.retail.v2alpha.SearchResponse.sponsored_results]. + + The field must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This should not be set when using the client side event + reporting with GTM or JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2alpha.UserEventService.CollectUserEvent] + or if + [direct_user_request][google.cloud.retail.v2alpha.UserInfo.direct_user_request] + is set. + direct_user_request (bool): + True if the request is made directly from the end user, in + which case the + [ip_address][google.cloud.retail.v2alpha.UserInfo.ip_address] + and + [user_agent][google.cloud.retail.v2alpha.UserInfo.user_agent] + can be populated from the HTTP request. This flag should be + set only if the API request is made directly from the end + user such as a mobile app (and not if a gateway or a server + is processing and pushing the user events). + + This should not be set when using the JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2alpha.UserEventService.CollectUserEvent]. + """ + + user_id: str = proto.Field( + proto.STRING, + number=1, + ) + ip_address: str = proto.Field( + proto.STRING, + number=2, + ) + user_agent: str = proto.Field( + proto.STRING, + number=3, + ) + direct_user_request: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class LocalInventory(proto.Message): + r"""The inventory information at a place (e.g. a store) + identified by a place ID. + + Attributes: + place_id (str): + The place ID for the current set of inventory + information. + price_info (google.cloud.retail_v2alpha.types.PriceInfo): + Product price and cost information. + + Google Merchant Center property + `price `__. + attributes (MutableMapping[str, google.cloud.retail_v2alpha.types.CustomAttribute]): + Additional local inventory attributes, for example, store + name, promotion tags, etc. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - At most 30 attributes are allowed. + - The key must be a UTF-8 encoded string with a length + limit of 32 characters. + - The key must match the pattern: + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, key0LikeThis + or KEY_1_LIKE_THIS. + - The attribute values must be of the same type (text or + number). + - Only 1 value is allowed for each attribute. + - For text values, the length limit is 256 UTF-8 + characters. + - The attribute does not support search. The ``searchable`` + field should be unset or set to false. + - The max summed total bytes of custom attribute keys and + values per product is 5MiB. + fulfillment_types (MutableSequence[str]): + Input only. Supported fulfillment types. Valid fulfillment + type values include commonly used types (such as pickup in + store and same day delivery), and custom types. Customers + have to map custom types to their display names before + rendering UI. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + All the elements must be distinct. Otherwise, an + INVALID_ARGUMENT error is returned. + """ + + place_id: str = proto.Field( + proto.STRING, + number=1, + ) + price_info: 'PriceInfo' = proto.Field( + proto.MESSAGE, + number=2, + message='PriceInfo', + ) + attributes: MutableMapping[str, 'CustomAttribute'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=3, + message='CustomAttribute', + ) + fulfillment_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/completion_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/completion_service.py new file mode 100644 index 00000000..e0247e1c --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/completion_service.py @@ -0,0 +1,312 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import search_service + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'CompleteQueryRequest', + 'CompleteQueryResponse', + }, +) + + +class CompleteQueryRequest(proto.Message): + r"""Autocomplete parameters. + + Attributes: + catalog (str): + Required. Catalog for which the completion is performed. + + Full resource name of catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + query (str): + Required. The query used to generate + suggestions. + The maximum number of allowed characters is 255. + visitor_id (str): + Required field. A unique identifier for tracking visitors. + For example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor logs in or out of the website. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + language_codes (MutableSequence[str]): + Note that this field applies for ``user-data`` dataset only. + For requests with ``cloud-retail`` dataset, setting this + field has no effect. + + The language filters applied to the output suggestions. If + set, it should contain the language of the query. If not + set, suggestions are returned without considering language + restrictions. This is the BCP-47 language code, such as + "en-US" or "sr-Latn". For more information, see `Tags for + Identifying + Languages `__. The + maximum number of language codes is 3. + device_type (str): + The device type context for completion suggestions. We + recommend that you leave this field empty. + + It can apply different suggestions on different device + types, e.g. ``DESKTOP``, ``MOBILE``. If it is empty, the + suggestions are across all device types. + + Supported formats: + + - ``UNKNOWN_DEVICE_TYPE`` + + - ``DESKTOP`` + + - ``MOBILE`` + + - A customized string starts with ``OTHER_``, e.g. + ``OTHER_IPHONE``. + dataset (str): + Determines which dataset to use for fetching completion. + "user-data" will use the imported dataset through + [CompletionService.ImportCompletionData][google.cloud.retail.v2alpha.CompletionService.ImportCompletionData]. + "cloud-retail" will use the dataset generated by cloud + retail based on user events. If leave empty, it will use the + "user-data". + + Current supported values: + + - user-data + + - cloud-retail: This option requires enabling auto-learning + function first. See + `guidelines `__. + max_suggestions (int): + Completion max suggestions. If left unset or set to 0, then + will fallback to the configured value + [CompletionConfig.max_suggestions][google.cloud.retail.v2alpha.CompletionConfig.max_suggestions]. + + The maximum allowed max suggestions is 20. If it is set + higher, it will be capped by 20. + enable_attribute_suggestions (bool): + If true, attribute suggestions are enabled + and provided in response. + This field is only available for "cloud-retail" + dataset. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2alpha.UserEvent.entity] + to get per-entity autocomplete results. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + query: str = proto.Field( + proto.STRING, + number=2, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=7, + ) + language_codes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + device_type: str = proto.Field( + proto.STRING, + number=4, + ) + dataset: str = proto.Field( + proto.STRING, + number=6, + ) + max_suggestions: int = proto.Field( + proto.INT32, + number=5, + ) + enable_attribute_suggestions: bool = proto.Field( + proto.BOOL, + number=9, + ) + entity: str = proto.Field( + proto.STRING, + number=10, + ) + + +class CompleteQueryResponse(proto.Message): + r"""Response of the autocomplete query. + + Attributes: + completion_results (MutableSequence[google.cloud.retail_v2alpha.types.CompleteQueryResponse.CompletionResult]): + Results of the matching suggestions. The + result list is ordered and the first result is + top suggestion. + attribution_token (str): + A unique complete token. This should be included in the + [UserEvent.completion_detail][google.cloud.retail.v2alpha.UserEvent.completion_detail] + for search events resulting from this completion, which + enables accurate attribution of complete model performance. + recent_search_results (MutableSequence[google.cloud.retail_v2alpha.types.CompleteQueryResponse.RecentSearchResult]): + Matched recent searches of this user. The maximum number of + recent searches is 10. This field is a restricted feature. + Contact Retail Search support team if you are interested in + enabling it. + + This feature is only available when + [CompleteQueryRequest.visitor_id][google.cloud.retail.v2alpha.CompleteQueryRequest.visitor_id] + field is set and + [UserEvent][google.cloud.retail.v2alpha.UserEvent] is + imported. The recent searches satisfy the follow rules: + + - They are ordered from latest to oldest. + + - They are matched with + [CompleteQueryRequest.query][google.cloud.retail.v2alpha.CompleteQueryRequest.query] + case insensitively. + + - They are transformed to lower case. + + - They are UTF-8 safe. + + Recent searches are deduplicated. More recent searches will + be reserved when duplication happens. + attribute_results (MutableMapping[str, google.cloud.retail_v2alpha.types.CompleteQueryResponse.AttributeResult]): + A map of matched attribute suggestions. This field is only + available for "cloud-retail" dataset. + + Current supported keys: + + - ``brands`` + + - ``categories`` + """ + + class CompletionResult(proto.Message): + r"""Resource that represents completion results. + + Attributes: + suggestion (str): + The suggestion for the query. + attributes (MutableMapping[str, google.cloud.retail_v2alpha.types.CustomAttribute]): + Custom attributes for the suggestion term. + + - For "user-data", the attributes are additional custom + attributes ingested through BigQuery. + + - For "cloud-retail", the attributes are product attributes + generated by Cloud Retail. It requires + [UserEvent.product_details][google.cloud.retail.v2alpha.UserEvent.product_details] + is imported properly. + facets (MutableSequence[google.cloud.retail_v2alpha.types.SearchResponse.Facet]): + Facet information for the suggestion term. + Gives the number of items resulting from a + search with this suggestion term for each facet. + + This is an experimental feature for limited + customers. Please reach out to the support team + if you would like to receive this information. + total_product_count (int): + Total number of products associated with a + search with this suggestion. + This is an experimental feature for limited + customers. Please reach out to the support team + if you would like to receive this information. + """ + + suggestion: str = proto.Field( + proto.STRING, + number=1, + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message=common.CustomAttribute, + ) + facets: MutableSequence[search_service.SearchResponse.Facet] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=search_service.SearchResponse.Facet, + ) + total_product_count: int = proto.Field( + proto.INT32, + number=4, + ) + + class RecentSearchResult(proto.Message): + r"""Recent search of this user. + + Attributes: + recent_search (str): + The recent search query. + """ + + recent_search: str = proto.Field( + proto.STRING, + number=1, + ) + + class AttributeResult(proto.Message): + r"""Resource that represents attribute results. + + Attributes: + suggestions (MutableSequence[str]): + The list of suggestions for the attribute. + """ + + suggestions: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + completion_results: MutableSequence[CompletionResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=CompletionResult, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=2, + ) + recent_search_results: MutableSequence[RecentSearchResult] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=RecentSearchResult, + ) + attribute_results: MutableMapping[str, AttributeResult] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=4, + message=AttributeResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control.py new file mode 100644 index 00000000..6d9bbb0c --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import search_service + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'Control', + }, +) + + +class Control(proto.Message): + r"""Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] and + affect search or recommendation results at serving time. + + 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: + facet_spec (google.cloud.retail_v2alpha.types.SearchRequest.FacetSpec): + A facet specification to perform faceted search. + + Note that this field is deprecated and will throw + NOT_IMPLEMENTED if used for creating a control. + + This field is a member of `oneof`_ ``control``. + rule (google.cloud.retail_v2alpha.types.Rule): + A rule control - a condition-action pair. + Enacts a set action when the condition is + triggered. For example: Boost "gShoe" when query + full matches "Running Shoes". + + This field is a member of `oneof`_ ``control``. + name (str): + Immutable. Fully qualified name + ``projects/*/locations/global/catalogs/*/controls/*`` + display_name (str): + Required. The human readable control display name. Used in + Retail UI. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is thrown. + associated_serving_config_ids (MutableSequence[str]): + Output only. List of [serving + config][google.cloud.retail.v2alpha.ServingConfig] ids that + are associated with this control in the same + [Catalog][google.cloud.retail.v2alpha.Catalog]. + + Note the association is managed via the + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig], + this is an output only denormalized view. + solution_types (MutableSequence[google.cloud.retail_v2alpha.types.SolutionType]): + Required. Immutable. The solution types that the control is + used for. Currently we support setting only one type of + solution at creation time. + + Only ``SOLUTION_TYPE_SEARCH`` value is supported at the + moment. If no solution type is provided at creation time, + will default to + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2alpha.SolutionType.SOLUTION_TYPE_SEARCH]. + search_solution_use_case (MutableSequence[google.cloud.retail_v2alpha.types.SearchSolutionUseCase]): + Specifies the use case for the control. Affects what + condition fields can be set. Only settable by search + controls. Will default to + [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2alpha.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + if not specified. Currently only allow one + search_solution_use_case per control. + """ + + facet_spec: search_service.SearchRequest.FacetSpec = proto.Field( + proto.MESSAGE, + number=3, + oneof='control', + message=search_service.SearchRequest.FacetSpec, + ) + rule: common.Rule = proto.Field( + proto.MESSAGE, + number=4, + oneof='control', + message=common.Rule, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + associated_serving_config_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + solution_types: MutableSequence[common.SolutionType] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=common.SolutionType, + ) + search_solution_use_case: MutableSequence[common.SearchSolutionUseCase] = proto.RepeatedField( + proto.ENUM, + number=7, + enum=common.SearchSolutionUseCase, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control_service.py new file mode 100644 index 00000000..77a3bd18 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/control_service.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 __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'CreateControlRequest', + 'UpdateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + }, +) + + +class CreateControlRequest(proto.Message): + r"""Request for CreateControl method. + + Attributes: + parent (str): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + control (google.cloud.retail_v2alpha.types.Control): + Required. The Control to create. + control_id (str): + Required. The ID to use for the Control, which will become + the final component of the Control's resource name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-_/. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + control: gcr_control.Control = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_control.Control, + ) + control_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class UpdateControlRequest(proto.Message): + r"""Request for UpdateControl method. + + Attributes: + control (google.cloud.retail_v2alpha.types.Control): + Required. The Control to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Control][google.cloud.retail.v2alpha.Control] to update. + The following are NOT supported: + + - [Control.name][google.cloud.retail.v2alpha.Control.name] + + If not set or empty, all supported fields are updated. + """ + + control: gcr_control.Control = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_control.Control, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteControlRequest(proto.Message): + r"""Request for DeleteControl method. + + Attributes: + name (str): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetControlRequest(proto.Message): + r"""Request for GetControl method. + + Attributes: + name (str): + Required. The resource name of the Control to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListControlsRequest(proto.Message): + r"""Request for ListControls method. + + Attributes: + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 50. Max + allowed value is 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListControls`` call. Provide this to retrieve the + subsequent page. + filter (str): + Optional. A filter to apply on the list results. Supported + features: + + - List all the products under the parent branch if + [filter][google.cloud.retail.v2alpha.ListControlsRequest.filter] + is unset. + - List controls that are used in a single ServingConfig: + 'serving_config = "boosted_home_page_cvr"' + """ + + 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, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListControlsResponse(proto.Message): + r"""Response for ListControls method. + + Attributes: + controls (MutableSequence[google.cloud.retail_v2alpha.types.Control]): + All the Controls for a given catalog. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + controls: MutableSequence[gcr_control.Control] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_control.Control, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/export_config.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/export_config.py new file mode 100644 index 00000000..2f7833cd --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/export_config.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'ExportErrorsConfig', + 'ExportMetadata', + 'ExportProductsResponse', + 'ExportUserEventsResponse', + 'OutputResult', + 'BigQueryOutputResult', + 'GcsOutputResult', + }, +) + + +class ExportErrorsConfig(proto.Message): + r"""Configuration of destination for Export related errors. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_prefix (str): + Google Cloud Storage path for import errors. This must be an + empty, existing Cloud Storage bucket. Export errors will be + written to a file in this bucket, one per line, as a + JSON-encoded ``google.rpc.Status`` message. + + This field is a member of `oneof`_ ``destination``. + """ + + gcs_prefix: str = proto.Field( + proto.STRING, + number=1, + oneof='destination', + ) + + +class ExportMetadata(proto.Message): + r"""Metadata related to the progress of the Export operation. + This is returned by the google.longrunning.Operation.metadata + field. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + +class ExportProductsResponse(proto.Message): + r"""Response of the ExportProductsRequest. If the long running + operation is done, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2alpha.types.ExportErrorsConfig): + This field is never set. + output_result (google.cloud.retail_v2alpha.types.OutputResult): + Output result indicating where the data were + exported to. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ExportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ExportErrorsConfig', + ) + output_result: 'OutputResult' = proto.Field( + proto.MESSAGE, + number=3, + message='OutputResult', + ) + + +class ExportUserEventsResponse(proto.Message): + r"""Response of the ExportUserEventsRequest. If the long running + operation was successful, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2alpha.types.ExportErrorsConfig): + This field is never set. + output_result (google.cloud.retail_v2alpha.types.OutputResult): + Output result indicating where the data were + exported to. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ExportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ExportErrorsConfig', + ) + output_result: 'OutputResult' = proto.Field( + proto.MESSAGE, + number=3, + message='OutputResult', + ) + + +class OutputResult(proto.Message): + r"""Output result that stores the information about where the + exported data is stored. + + Attributes: + bigquery_result (MutableSequence[google.cloud.retail_v2alpha.types.BigQueryOutputResult]): + The BigQuery location where the result is + stored. + gcs_result (MutableSequence[google.cloud.retail_v2alpha.types.GcsOutputResult]): + The Google Cloud Storage location where the + result is stored. + """ + + bigquery_result: MutableSequence['BigQueryOutputResult'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='BigQueryOutputResult', + ) + gcs_result: MutableSequence['GcsOutputResult'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='GcsOutputResult', + ) + + +class BigQueryOutputResult(proto.Message): + r"""A BigQuery output result. + + Attributes: + dataset_id (str): + The ID of a BigQuery Dataset. + table_id (str): + The ID of a BigQuery Table. + """ + + dataset_id: str = proto.Field( + proto.STRING, + number=1, + ) + table_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GcsOutputResult(proto.Message): + r"""A Gcs output result. + + Attributes: + output_uri (str): + The uri of Gcs output + """ + + output_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/import_config.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/import_config.py new file mode 100644 index 00000000..75907797 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/import_config.py @@ -0,0 +1,749 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import user_event +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 google.type import date_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'GcsSource', + 'BigQuerySource', + 'ProductInlineSource', + 'UserEventInlineSource', + 'ImportErrorsConfig', + 'ImportProductsRequest', + 'ImportUserEventsRequest', + 'ImportCompletionDataRequest', + 'ProductInputConfig', + 'UserEventInputConfig', + 'CompletionDataInputConfig', + 'ImportMetadata', + 'TransformedUserEventsMetadata', + 'ImportProductsResponse', + 'ImportUserEventsResponse', + 'UserEventImportSummary', + 'ImportCompletionDataResponse', + }, +) + + +class GcsSource(proto.Message): + r"""Google Cloud Storage location for input content. + + Attributes: + input_uris (MutableSequence[str]): + Required. Google Cloud Storage URIs to input files. URI can + be up to 2000 characters long. URIs can match the full + object path (for example, + ``gs://bucket/directory/object.json``) or a pattern matching + one or more files, such as ``gs://bucket/directory/*.json``. + A request can contain at most 100 files, and each file can + be up to 2 GB. See `Importing product + information `__ + for the expected file format and setup instructions. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2alpha.Product] per line. + Each product must have a valid + [Product.id][google.cloud.retail.v2alpha.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2alpha.UserEvent] per + line. + - ``user_event_ga360``: Using + https://support.google.com/analytics/answer/3437719. + + Supported values for control imports: + + - ``control`` (default): One JSON + [Control][google.cloud.retail.v2alpha.Control] per line. + + Supported values for catalog attribute imports: + + - ``catalog_attribute`` (default): One CSV + [CatalogAttribute][google.cloud.retail.v2alpha.CatalogAttribute] + per line. + """ + + input_uris: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + data_schema: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BigQuerySource(proto.Message): + r"""BigQuery source import data from. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + partition_date (google.type.date_pb2.Date): + BigQuery time partitioned table's \_PARTITIONDATE in + YYYY-MM-DD format. + + Only supported in + [ImportProductsRequest][google.cloud.retail.v2alpha.ImportProductsRequest]. + + This field is a member of `oneof`_ ``partition``. + project_id (str): + The project ID (can be project # or ID) that + the BigQuery source is in with a length limit of + 128 characters. If not specified, inherits the + project ID from the parent request. + dataset_id (str): + Required. The BigQuery data set to copy the + data from with a length limit of 1,024 + characters. + table_id (str): + Required. The BigQuery table to copy the data + from with a length limit of 1,024 characters. + gcs_staging_dir (str): + Intermediate Cloud Storage directory used for + the import with a length limit of 2,000 + characters. Can be specified if one wants to + have the BigQuery export to a specific Cloud + Storage directory. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2alpha.Product] per line. + Each product must have a valid + [Product.id][google.cloud.retail.v2alpha.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2alpha.UserEvent] per + line. + - ``user_event_ga360``: The schema is available here: + https://support.google.com/analytics/answer/3437719. + - ``user_event_ga4``: The schema is available here: + https://support.google.com/analytics/answer/7029846. + + Supported values for autocomplete imports: + + - ``suggestions`` (default): One JSON completion suggestion + per line. + - ``denylist``: One JSON deny suggestion per line. + - ``allowlist``: One JSON allow suggestion per line. + """ + + partition_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=6, + oneof='partition', + message=date_pb2.Date, + ) + project_id: str = proto.Field( + proto.STRING, + number=5, + ) + dataset_id: str = proto.Field( + proto.STRING, + number=1, + ) + table_id: str = proto.Field( + proto.STRING, + number=2, + ) + gcs_staging_dir: str = proto.Field( + proto.STRING, + number=3, + ) + data_schema: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ProductInlineSource(proto.Message): + r"""The inline source for the input config for ImportProducts + method. + + Attributes: + products (MutableSequence[google.cloud.retail_v2alpha.types.Product]): + Required. A list of products to update/create. Each product + must have a valid + [Product.id][google.cloud.retail.v2alpha.Product.id]. + Recommended max of 100 items. + """ + + products: MutableSequence[product.Product] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=product.Product, + ) + + +class UserEventInlineSource(proto.Message): + r"""The inline source for the input config for ImportUserEvents + method. + + Attributes: + user_events (MutableSequence[google.cloud.retail_v2alpha.types.UserEvent]): + Required. A list of user events to import. + Recommended max of 10k items. + """ + + user_events: MutableSequence[user_event.UserEvent] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=user_event.UserEvent, + ) + + +class ImportErrorsConfig(proto.Message): + r"""Configuration of destination for Import related errors. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_prefix (str): + Google Cloud Storage prefix for import errors. This must be + an empty, existing Cloud Storage directory. Import errors + are written to sharded files in this directory, one per + line, as a JSON-encoded ``google.rpc.Status`` message. + + This field is a member of `oneof`_ ``destination``. + """ + + gcs_prefix: str = proto.Field( + proto.STRING, + number=1, + oneof='destination', + ) + + +class ImportProductsRequest(proto.Message): + r"""Request message for Import methods. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog/branches/default_branch`` + + If no updateMask is specified, requires products.create + permission. If updateMask is specified, requires + products.update permission. + request_id (str): + Deprecated. This field has no effect. + input_config (google.cloud.retail_v2alpha.types.ProductInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2alpha.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided imported ``products`` + to update. If not set, all fields are updated. + reconciliation_mode (google.cloud.retail_v2alpha.types.ImportProductsRequest.ReconciliationMode): + The mode of reconciliation between existing products and the + products to be imported. Defaults to + [ReconciliationMode.INCREMENTAL][google.cloud.retail.v2alpha.ImportProductsRequest.ReconciliationMode.INCREMENTAL]. + notification_pubsub_topic (str): + Full Pub/Sub topic name for receiving notification. If this + field is set, when the import is finished, a notification is + sent to specified Pub/Sub topic. The message data is JSON + string of a [Operation][google.longrunning.Operation]. + + Format of the Pub/Sub topic is + ``projects/{project}/topics/{topic}``. It has to be within + the same project as + [ImportProductsRequest.parent][google.cloud.retail.v2alpha.ImportProductsRequest.parent]. + Make sure that + ``service-@gcp-sa-retail.iam.gserviceaccount.com`` + has the ``pubsub.topics.publish`` IAM permission on the + topic. + skip_default_branch_protection (bool): + If true, this performs the FULL import even if it would + delete a large proportion of the products in the default + branch, which could potentially cause outages if you have + live predict/search traffic. + + Only supported when + [ImportProductsRequest.reconciliation_mode][google.cloud.retail.v2alpha.ImportProductsRequest.reconciliation_mode] + is set to ``FULL``. + """ + class ReconciliationMode(proto.Enum): + r"""Indicates how imported products are reconciled with the + existing products created or imported before. + + Values: + RECONCILIATION_MODE_UNSPECIFIED (0): + Defaults to INCREMENTAL. + INCREMENTAL (1): + Inserts new products or updates existing + products. + FULL (2): + Calculates diff and replaces the entire + product dataset. Existing products may be + deleted if they are not present in the source + location. + """ + RECONCILIATION_MODE_UNSPECIFIED = 0 + INCREMENTAL = 1 + FULL = 2 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + request_id: str = proto.Field( + proto.STRING, + number=6, + ) + input_config: 'ProductInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductInputConfig', + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=3, + message='ImportErrorsConfig', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + reconciliation_mode: ReconciliationMode = proto.Field( + proto.ENUM, + number=5, + enum=ReconciliationMode, + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=7, + ) + skip_default_branch_protection: bool = proto.Field( + proto.BOOL, + number=8, + ) + + +class ImportUserEventsRequest(proto.Message): + r"""Request message for the ImportUserEvents request. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog`` + input_config (google.cloud.retail_v2alpha.types.UserEventInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2alpha.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. Cannot be set for inline user + event imports. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'UserEventInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='UserEventInputConfig', + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=3, + message='ImportErrorsConfig', + ) + + +class ImportCompletionDataRequest(proto.Message): + r"""Request message for ImportCompletionData methods. + + Attributes: + parent (str): + Required. The catalog which the suggestions dataset belongs + to. + + Format: + ``projects/1234/locations/global/catalogs/default_catalog``. + input_config (google.cloud.retail_v2alpha.types.CompletionDataInputConfig): + Required. The desired input location of the + data. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'CompletionDataInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='CompletionDataInputConfig', + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ProductInputConfig(proto.Message): + r"""The input config source for products. + + 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_inline_source (google.cloud.retail_v2alpha.types.ProductInlineSource): + The Inline source for the input content for + products. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2alpha.types.GcsSource): + Google Cloud Storage location for the input + content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2alpha.types.BigQuerySource): + BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + product_inline_source: 'ProductInlineSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='ProductInlineSource', + ) + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class UserEventInputConfig(proto.Message): + r"""The input config source for user events. + + 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: + user_event_inline_source (google.cloud.retail_v2alpha.types.UserEventInlineSource): + Required. The Inline source for the input + content for UserEvents. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2alpha.types.GcsSource): + Required. Google Cloud Storage location for + the input content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2alpha.types.BigQuerySource): + Required. BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + user_event_inline_source: 'UserEventInlineSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='UserEventInlineSource', + ) + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class CompletionDataInputConfig(proto.Message): + r"""The input config source for completion data. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + big_query_source (google.cloud.retail_v2alpha.types.BigQuerySource): + Required. BigQuery input source. + + Add the IAM permission "BigQuery Data Viewer" + for + cloud-retail-customer-data-access@system.gserviceaccount.com + before using this feature otherwise an error is + thrown. + + This field is a member of `oneof`_ ``source``. + """ + + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='BigQuerySource', + ) + + +class ImportMetadata(proto.Message): + r"""Metadata related to the progress of the Import operation. + This is returned by the google.longrunning.Operation.metadata + field. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + success_count (int): + Count of entries that were processed + successfully. + failure_count (int): + Count of entries that encountered errors + while processing. + request_id (str): + Deprecated. This field is never set. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. + transformed_user_events_metadata (google.cloud.retail_v2alpha.types.TransformedUserEventsMetadata): + Metadata related to transform user events. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + success_count: int = proto.Field( + proto.INT64, + number=3, + ) + failure_count: int = proto.Field( + proto.INT64, + number=4, + ) + request_id: str = proto.Field( + proto.STRING, + number=5, + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=6, + ) + transformed_user_events_metadata: 'TransformedUserEventsMetadata' = proto.Field( + proto.MESSAGE, + number=7, + message='TransformedUserEventsMetadata', + ) + + +class TransformedUserEventsMetadata(proto.Message): + r"""Metadata related to transform user events operation. + + Attributes: + source_events_count (int): + Count of entries in the source user events + BigQuery table. + transformed_events_count (int): + Count of entries in the transformed user + events BigQuery table, which could be different + from the actually imported number of user + events. + """ + + source_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + transformed_events_count: int = proto.Field( + proto.INT64, + number=2, + ) + + +class ImportProductsResponse(proto.Message): + r"""Response of the + [ImportProductsRequest][google.cloud.retail.v2alpha.ImportProductsRequest]. + If the long running operation is done, then this message is returned + by the google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2alpha.types.ImportErrorsConfig): + Echoes the destination for the complete + errors in the request if set. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + + +class ImportUserEventsResponse(proto.Message): + r"""Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2alpha.types.ImportErrorsConfig): + Echoes the destination for the complete + errors if this field was set in the request. + import_summary (google.cloud.retail_v2alpha.types.UserEventImportSummary): + Aggregated statistics of user event import + status. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + import_summary: 'UserEventImportSummary' = proto.Field( + proto.MESSAGE, + number=3, + message='UserEventImportSummary', + ) + + +class UserEventImportSummary(proto.Message): + r"""A summary of import result. The UserEventImportSummary + summarizes the import status for user events. + + Attributes: + joined_events_count (int): + Count of user events imported with complete + existing catalog information. + unjoined_events_count (int): + Count of user events imported, but with + catalog information not found in the imported + catalog. + """ + + joined_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + unjoined_events_count: int = proto.Field( + proto.INT64, + number=2, + ) + + +class ImportCompletionDataResponse(proto.Message): + r"""Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2alpha.ImportCompletionDataRequest]. + If the long running operation is done, this message is returned by + the google.longrunning.Operations.response field if the operation is + successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link.py new file mode 100644 index 00000000..21a4d553 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link.py @@ -0,0 +1,194 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'MerchantCenterAccountLink', + 'CreateMerchantCenterAccountLinkMetadata', + }, +) + + +class MerchantCenterAccountLink(proto.Message): + r"""Represents a link between a Merchant Center account and a + branch. Once a link is established, products from the linked + merchant center account will be streamed to the linked branch. + + Attributes: + name (str): + Output only. Immutable. Full resource name of the Merchant + Center Account Link, such as + ``projects/*/locations/global/catalogs/default_catalog/merchantCenterAccountLinks/merchant_center_account_link``. + id (str): + Output only. Immutable. + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + identifier, which is the final component of + [name][google.cloud.retail.v2alpha.MerchantCenterAccountLink.name]. + This field is auto generated and follows the convention: + ``BranchId_MerchantCenterAccountId``. + ``projects/*/locations/global/catalogs/default_catalog/merchantCenterAccountLinks/id_1``. + merchant_center_account_id (int): + Required. The linked `Merchant center account + id `__. + The account must be a standalone account or a sub-account of + a MCA. + branch_id (str): + Required. The branch id (e.g. 0/1/2) within the catalog that + products from merchant_center_account_id are streamed to. + When updating this field, an empty value will use the + currently configured default branch. However, changing the + default branch later on won't change the linked branch here. + + A single branch id can only have one linked merchant center + account id. + feed_label (str): + The FeedLabel used to perform filtering. Note: this replaces + `region_id `__. + + Example value: ``US``. Example value: ``FeedLabel1``. + language_code (str): + Language of the title/description and other string + attributes. Use language tags defined by `BCP + 47 `__. ISO + 639-1. + + This specifies the language of offers in Merchant Center + that will be accepted. If empty, no language filtering will + be performed. + + Example value: ``en``. + feed_filters (MutableSequence[google.cloud.retail_v2alpha.types.MerchantCenterAccountLink.MerchantCenterFeedFilter]): + Criteria for the Merchant Center feeds to be + ingested via the link. All offers will be + ingested if the list is empty. Otherwise the + offers will be ingested from selected feeds. + state (google.cloud.retail_v2alpha.types.MerchantCenterAccountLink.State): + Output only. Represents the state of the + link. + project_id (str): + Output only. GCP project ID. + """ + class State(proto.Enum): + r"""The state of the link. + + Values: + STATE_UNSPECIFIED (0): + Default value. + PENDING (1): + Link is created and LRO is not complete. + ACTIVE (2): + Link is active. + FAILED (3): + Link creation failed. + """ + STATE_UNSPECIFIED = 0 + PENDING = 1 + ACTIVE = 2 + FAILED = 3 + + class MerchantCenterFeedFilter(proto.Message): + r"""Merchant Center Feed filter criterion. + + Attributes: + primary_feed_id (int): + Merchant Center primary feed ID. + primary_feed_name (str): + Merchant Center primary feed name. The name + is used for the display purposes only. + """ + + primary_feed_id: int = proto.Field( + proto.INT64, + number=1, + ) + primary_feed_name: str = proto.Field( + proto.STRING, + number=2, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=8, + ) + merchant_center_account_id: int = proto.Field( + proto.INT64, + number=2, + ) + branch_id: str = proto.Field( + proto.STRING, + number=3, + ) + feed_label: str = proto.Field( + proto.STRING, + number=4, + ) + language_code: str = proto.Field( + proto.STRING, + number=5, + ) + feed_filters: MutableSequence[MerchantCenterFeedFilter] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message=MerchantCenterFeedFilter, + ) + state: State = proto.Field( + proto.ENUM, + number=7, + enum=State, + ) + project_id: str = proto.Field( + proto.STRING, + number=9, + ) + + +class CreateMerchantCenterAccountLinkMetadata(proto.Message): + r"""Common metadata related to the progress of the operations. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link_service.py new file mode 100644 index 00000000..0f5a3f89 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/merchant_center_account_link_service.py @@ -0,0 +1,120 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import merchant_center_account_link as gcr_merchant_center_account_link + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'ListMerchantCenterAccountLinksRequest', + 'ListMerchantCenterAccountLinksResponse', + 'CreateMerchantCenterAccountLinkRequest', + 'DeleteMerchantCenterAccountLinkRequest', + }, +) + + +class ListMerchantCenterAccountLinksRequest(proto.Message): + r"""Request for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + Attributes: + parent (str): + Required. The parent Catalog of the resource. It must match + this format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID} + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListMerchantCenterAccountLinksResponse(proto.Message): + r"""Response for + [MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks] + method. + + Attributes: + merchant_center_account_links (MutableSequence[google.cloud.retail_v2alpha.types.MerchantCenterAccountLink]): + The links. + """ + + merchant_center_account_links: MutableSequence[gcr_merchant_center_account_link.MerchantCenterAccountLink] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_merchant_center_account_link.MerchantCenterAccountLink, + ) + + +class CreateMerchantCenterAccountLinkRequest(proto.Message): + r"""Request for + [MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink] + method. + + Attributes: + parent (str): + Required. The branch resource where this + MerchantCenterAccountLink will be created. Format: + projects/{PROJECT_NUMBER}/locations/global/catalogs/{CATALOG_ID}} + merchant_center_account_link (google.cloud.retail_v2alpha.types.MerchantCenterAccountLink): + Required. The + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink] + to create. + + If the caller does not have permission to create the + [MerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLink], + regardless of whether or not it exists, a PERMISSION_DENIED + error is returned. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + merchant_center_account_link: gcr_merchant_center_account_link.MerchantCenterAccountLink = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_merchant_center_account_link.MerchantCenterAccountLink, + ) + + +class DeleteMerchantCenterAccountLinkRequest(proto.Message): + r"""Request for + [MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink][google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink] + method. + + Attributes: + name (str): + Required. Full resource name. Format: + projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/merchantCenterAccountLinks/{merchant_center_account_link_id} + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model.py new file mode 100644 index 00000000..df4a3c0f --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model.py @@ -0,0 +1,583 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'Model', + }, +) + + +class Model(proto.Message): + r"""Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2alpha.Model]. A + [Model][google.cloud.retail.v2alpha.Model] can be associated with a + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] and then + queried through the Predict API. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + page_optimization_config (google.cloud.retail_v2alpha.types.Model.PageOptimizationConfig): + Optional. The page optimization config. + + This field is a member of `oneof`_ ``training_config``. + name (str): + Required. The fully qualified resource name of the model. + + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + catalog_id has char limit of 50. recommendation_model_id has + char limit of 40. + display_name (str): + Required. The display name of the model. + + Should be human readable, used to display + Recommendation Models in the Retail Cloud + Console Dashboard. UTF-8 encoded string with + limit of 1024 characters. + training_state (google.cloud.retail_v2alpha.types.Model.TrainingState): + Optional. The training state that the model is in (e.g. + ``TRAINING`` or ``PAUSED``). + + Since part of the cost of running the service is frequency + of training - this can be used to determine when to train + model in order to control cost. If not specified: the + default value for ``CreateModel`` method is ``TRAINING``. + The default value for ``UpdateModel`` method is to keep the + state the same as before. + serving_state (google.cloud.retail_v2alpha.types.Model.ServingState): + Output only. The serving state of the model: ``ACTIVE``, + ``NOT_ACTIVE``. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was created at. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was last updated. E.g. if a Recommendation + Model was paused - this would be the time the + pause was initiated. + type_ (str): + Required. The type of model e.g. ``home-page``. + + Currently supported values: ``recommended-for-you``, + ``others-you-may-like``, ``frequently-bought-together``, + ``page-optimization``, ``similar-items``, ``buy-it-again``, + ``on-sale-items``, and ``recently-viewed``\ (readonly + value). + + This field together with + [optimization_objective][google.cloud.retail.v2alpha.Model.optimization_objective] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + optimization_objective (str): + Optional. The optimization objective e.g. ``cvr``. + + Currently supported values: ``ctr``, ``cvr``, + ``revenue-per-order``. + + If not specified, we choose default based on model type. + Default depends on type of recommendation: + + ``recommended-for-you`` => ``ctr`` + + ``others-you-may-like`` => ``ctr`` + + ``frequently-bought-together`` => ``revenue_per_order`` + + This field together with + [optimization_objective][google.cloud.retail.v2alpha.Model.type] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + periodic_tuning_state (google.cloud.retail_v2alpha.types.Model.PeriodicTuningState): + Optional. The state of periodic tuning. + + The period we use is 3 months - to do a one-off tune earlier + use the ``TuneModel`` method. Default value is + ``PERIODIC_TUNING_ENABLED``. + last_tune_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp when the latest + successful tune finished. + tuning_operation (str): + Output only. The tune operation associated + with the model. + Can be used to determine if there is an ongoing + tune for this recommendation. Empty field + implies no tune is goig on. + data_state (google.cloud.retail_v2alpha.types.Model.DataState): + Output only. The state of data requirements for this model: + ``DATA_OK`` and ``DATA_ERROR``. + + Recommendation model cannot be trained if the data is in + ``DATA_ERROR`` state. Recommendation model can have + ``DATA_ERROR`` state even if serving state is ``ACTIVE``: + models were trained successfully before, but cannot be + refreshed because model no longer has sufficient data for + training. + filtering_option (google.cloud.retail_v2alpha.types.RecommendationsFilteringOption): + Optional. If ``RECOMMENDATIONS_FILTERING_ENABLED``, + recommendation filtering by attributes is enabled for the + model. + serving_config_lists (MutableSequence[google.cloud.retail_v2alpha.types.Model.ServingConfigList]): + Output only. The list of valid serving + configs associated with the + PageOptimizationConfig. + """ + class ServingState(proto.Enum): + r"""The serving state of the model. + + Values: + SERVING_STATE_UNSPECIFIED (0): + Unspecified serving state. + INACTIVE (1): + The model is not serving. + ACTIVE (2): + The model is serving and can be queried. + TUNED (3): + The model is trained on tuned hyperparameters + and can be queried. + """ + SERVING_STATE_UNSPECIFIED = 0 + INACTIVE = 1 + ACTIVE = 2 + TUNED = 3 + + class TrainingState(proto.Enum): + r"""The training state of the model. + + Values: + TRAINING_STATE_UNSPECIFIED (0): + Unspecified training state. + PAUSED (1): + The model training is paused. + TRAINING (2): + The model is training. + """ + TRAINING_STATE_UNSPECIFIED = 0 + PAUSED = 1 + TRAINING = 2 + + class PeriodicTuningState(proto.Enum): + r"""Describes whether periodic tuning is enabled for this model or not. + Periodic tuning is scheduled at most every three months. You can + start a tuning process manually by using the ``TuneModel`` method, + which starts a tuning process immediately and resets the quarterly + schedule. Enabling or disabling periodic tuning does not affect any + current tuning processes. + + Values: + PERIODIC_TUNING_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + PERIODIC_TUNING_DISABLED (1): + The model has periodic tuning disabled. Tuning can be + reenabled by calling the ``EnableModelPeriodicTuning`` + method or by calling the ``TuneModel`` method. + ALL_TUNING_DISABLED (3): + The model cannot be tuned with periodic tuning OR the + ``TuneModel`` method. Hide the options in customer UI and + reject any requests through the backend self serve API. + PERIODIC_TUNING_ENABLED (2): + The model has periodic tuning enabled. Tuning can be + disabled by calling the ``DisableModelPeriodicTuning`` + method. + """ + PERIODIC_TUNING_STATE_UNSPECIFIED = 0 + PERIODIC_TUNING_DISABLED = 1 + ALL_TUNING_DISABLED = 3 + PERIODIC_TUNING_ENABLED = 2 + + class DataState(proto.Enum): + r"""Describes whether this model have sufficient training data + to be continuously trained. + + Values: + DATA_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + DATA_OK (1): + The model has sufficient training data. + DATA_ERROR (2): + The model does not have sufficient training + data. Error messages can be queried via + Stackdriver. + """ + DATA_STATE_UNSPECIFIED = 0 + DATA_OK = 1 + DATA_ERROR = 2 + + class PageOptimizationConfig(proto.Message): + r"""The PageOptimizationConfig for model training. + + This determines how many panels to optimize for, and which serving + configs to consider for each panel. The purpose of this model is to + optimize which + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] to show + on which panels in way that optimizes the visitors shopping journey. + + Attributes: + page_optimization_event_type (str): + Required. The type of + [UserEvent][google.cloud.retail.v2alpha.UserEvent] this page + optimization is shown for. + + Each page has an associated event type - this will be the + corresponding event type for the page that the page + optimization model is used on. + + Supported types: + + - ``add-to-cart``: Products being added to cart. + - ``detail-page-view``: Products detail page viewed. + - ``home-page-view``: Homepage viewed + - ``category-page-view``: Homepage viewed + - ``shopping-cart-page-view``: User viewing a shopping + cart. + + ``home-page-view`` only allows models with type + ``recommended-for-you``. All other + page_optimization_event_type allow all + [Model.types][google.cloud.retail.v2alpha.Model.type]. + panels (MutableSequence[google.cloud.retail_v2alpha.types.Model.PageOptimizationConfig.Panel]): + Required. A list of panel configurations. + + Limit = 5. + restriction (google.cloud.retail_v2alpha.types.Model.PageOptimizationConfig.Restriction): + Optional. How to restrict results across panels e.g. can the + same + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + be shown on multiple panels at once. + + If unspecified, default to ``UNIQUE_MODEL_RESTRICTION``. + """ + class Restriction(proto.Enum): + r"""Restrictions of expected returned results. + + Values: + RESTRICTION_UNSPECIFIED (0): + Unspecified value for restriction. + NO_RESTRICTION (1): + Allow any + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + to be show on any number of panels. + + Example: + + ``Panel1 candidates``: pdp_ctr, pdp_cvr, + home_page_ctr_no_diversity + + ``Panel2 candidates``: home_page_ctr_no_diversity, + home_page_ctr_diversity, pdp_cvr_no_diversity + + ``Restriction`` = NO_RESTRICTION + + ``Valid combinations``: + + - (pdp_ctr, home_page_ctr_no_diversity) + - (pdp_ctr, home_page_ctr_diversity) + - (pdp_ctr, pdp_cvr_no_diversity) + - (pdp_cvr, home_page_ctr_no_diversity) + - (pdp_cvr, home_page_ctr_diversity) + - (pdp_cvr, pdp_cvr_no_diversity) + - (home_page_ctr_no_diversity, home_page_ctr_no_diversity) + - (home_page_ctr_no_diversity, home_page_ctr_diversity) + - (home_page_ctr_no_diversity, pdp_cvr_no_diversity) + + ``Invalid combinations``: [] + UNIQUE_SERVING_CONFIG_RESTRICTION (2): + Do not allow the same + [ServingConfig.name][google.cloud.retail.v2alpha.ServingConfig.name] + to be shown on multiple panels. + + Example: + + ``Panel1 candidates``: pdp_ctr, pdp_cvr, + home_page_ctr_no_diversity + + ``Panel2 candidates``: home_page_ctr_no_diversity, + home_page_ctr_diversity_low, pdp_cvr_no_diversity + + ``Restriction`` = ``UNIQUE_SERVING_CONFIG_RESTRICTION`` + + ``Valid combinations``: + + - (pdp_ctr, home_page_ctr_no_diversity) + - (pdp_ctr, home_page_ctr_diversity_low) + - (pdp_ctr, pdp_cvr_no_diversity) + - (pdp_ctr, pdp_cvr_no_diversity) + - (pdp_cvr, home_page_ctr_no_diversity) + - (pdp_cvr, home_page_ctr_diversity_low) + - (pdp_cvr, pdp_cvr_no_diversity) + - (home_page_ctr_no_diversity, home_page_ctr_diversity_low) + - (home_page_ctr_no_diversity, pdp_cvr_no_diversity) + + ``Invalid combinations``: + + - (home_page_ctr_no_diversity, home_page_ctr_no_diversity) + UNIQUE_MODEL_RESTRICTION (3): + Do not allow multiple + [ServingConfigs][google.cloud.retail.v2alpha.ServingConfig] + with same + [Model.name][google.cloud.retail.v2alpha.Model.name] to be + show on on different panels. + + Example: + + ``Panel1 candidates``: pdp_ctr, pdp_cvr, + home_page_ctr_no_diversity + + ``Panel2 candidates``: home_page_ctr_no_diversity, + home_page_ctr_diversity_low, pdp_cvr_no_diversity + + ``Restriction`` = ``UNIQUE_MODEL_RESTRICTION`` + + ``Valid combinations``: + + - (pdp_ctr, home_page_ctr_no_diversity) + - (pdp_ctr, home_page_ctr_diversity) + - (pdp_ctr, pdp_cvr_no_diversity) + - (pdp_ctr, pdp_cvr_no_diversity) + - (pdp_cvr, home_page_ctr_no_diversity) + - (pdp_cvr, home_page_ctr_diversity_low) + - (home_page_ctr_no_diversity, pdp_cvr_no_diversity) + + ``Invalid combinations``: + + - (home_page_ctr_no_diversity, home_page_ctr_no_diversity) + - (pdp_cvr, pdp_cvr_no_diversity) + UNIQUE_MODEL_TYPE_RESTRICTION (4): + Do not allow multiple + [ServingConfigs][google.cloud.retail.v2alpha.ServingConfig] + with same + [Model.type][google.cloud.retail.v2alpha.Model.type] to be + shown on different panels. + + Example: + + ``Panel1 candidates``: pdp_ctr, pdp_cvr, + home_page_ctr_no_diversity + + ``Panel2 candidates``: home_page_ctr_no_diversity, + home_page_ctr_diversity_low, pdp_cvr_no_diversity + + ``Restriction`` = ``UNIQUE_MODEL_RESTRICTION`` + + ``Valid combinations``: + + - (pdp_ctr, home_page_ctr_no_diversity) + - (pdp_ctr, home_page_ctr_diversity) + - (pdp_cvr, home_page_ctr_no_diversity) + - (pdp_cvr, home_page_ctr_diversity_low) + - (home_page_ctr_no_diversity, pdp_cvr_no_diversity) + + ``Invalid combinations``: + + - (pdp_ctr, pdp_cvr_no_diversity) + - (pdp_ctr, pdp_cvr_no_diversity) + - (pdp_cvr, pdp_cvr_no_diversity) + - (home_page_ctr_no_diversity, home_page_ctr_no_diversity) + - (home_page_ctr_no_diversity, home_page_ctr_diversity) + """ + RESTRICTION_UNSPECIFIED = 0 + NO_RESTRICTION = 1 + UNIQUE_SERVING_CONFIG_RESTRICTION = 2 + UNIQUE_MODEL_RESTRICTION = 3 + UNIQUE_MODEL_TYPE_RESTRICTION = 4 + + class Candidate(proto.Message): + r"""A candidate to consider for a given panel. Currently only + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] are valid + candidates. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + serving_config_id (str): + This has to be a valid + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + identifier. For example, for a ServingConfig with full name: + ``projects/*/locations/global/catalogs/default_catalog/servingConfigs/my_candidate_config``, + this would be ``my_candidate_config``. + + This field is a member of `oneof`_ ``candidate``. + """ + + serving_config_id: str = proto.Field( + proto.STRING, + number=1, + oneof='candidate', + ) + + class Panel(proto.Message): + r"""An individual panel with a list of + [ServingConfigs][google.cloud.retail.v2alpha.ServingConfig] to + consider for it. + + Attributes: + display_name (str): + Optional. The name to display for the panel. + candidates (MutableSequence[google.cloud.retail_v2alpha.types.Model.PageOptimizationConfig.Candidate]): + Required. The candidates to consider on the + panel. + default_candidate (google.cloud.retail_v2alpha.types.Model.PageOptimizationConfig.Candidate): + Required. The default candidate. If the model + fails at serving time, we fall back to the + default. + """ + + display_name: str = proto.Field( + proto.STRING, + number=1, + ) + candidates: MutableSequence['Model.PageOptimizationConfig.Candidate'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Model.PageOptimizationConfig.Candidate', + ) + default_candidate: 'Model.PageOptimizationConfig.Candidate' = proto.Field( + proto.MESSAGE, + number=3, + message='Model.PageOptimizationConfig.Candidate', + ) + + page_optimization_event_type: str = proto.Field( + proto.STRING, + number=1, + ) + panels: MutableSequence['Model.PageOptimizationConfig.Panel'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='Model.PageOptimizationConfig.Panel', + ) + restriction: 'Model.PageOptimizationConfig.Restriction' = proto.Field( + proto.ENUM, + number=3, + enum='Model.PageOptimizationConfig.Restriction', + ) + + class ServingConfigList(proto.Message): + r"""Represents an ordered combination of valid serving configs, which + can be used for ``PAGE_OPTIMIZATION`` recommendations. + + Attributes: + serving_config_ids (MutableSequence[str]): + Optional. A set of valid serving configs that may be used + for ``PAGE_OPTIMIZATION``. + """ + + serving_config_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + page_optimization_config: PageOptimizationConfig = proto.Field( + proto.MESSAGE, + number=17, + oneof='training_config', + message=PageOptimizationConfig, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + training_state: TrainingState = proto.Field( + proto.ENUM, + number=3, + enum=TrainingState, + ) + serving_state: ServingState = proto.Field( + proto.ENUM, + number=4, + enum=ServingState, + ) + 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, + ) + type_: str = proto.Field( + proto.STRING, + number=7, + ) + optimization_objective: str = proto.Field( + proto.STRING, + number=8, + ) + periodic_tuning_state: PeriodicTuningState = proto.Field( + proto.ENUM, + number=11, + enum=PeriodicTuningState, + ) + last_tune_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + tuning_operation: str = proto.Field( + proto.STRING, + number=15, + ) + data_state: DataState = proto.Field( + proto.ENUM, + number=16, + enum=DataState, + ) + filtering_option: common.RecommendationsFilteringOption = proto.Field( + proto.ENUM, + number=18, + enum=common.RecommendationsFilteringOption, + ) + serving_config_lists: MutableSequence[ServingConfigList] = proto.RepeatedField( + proto.MESSAGE, + number=19, + message=ServingConfigList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model_service.py new file mode 100644 index 00000000..ee356a9d --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/model_service.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import model as gcr_model +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'CreateModelRequest', + 'UpdateModelRequest', + 'GetModelRequest', + 'PauseModelRequest', + 'ResumeModelRequest', + 'ListModelsRequest', + 'DeleteModelRequest', + 'ListModelsResponse', + 'TuneModelRequest', + 'CreateModelMetadata', + 'TuneModelMetadata', + 'TuneModelResponse', + }, +) + + +class CreateModelRequest(proto.Message): + r"""Request for creating a model. + + Attributes: + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + model (google.cloud.retail_v2alpha.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2alpha.Model] to create. + dry_run (bool): + Optional. Whether to run a dry run to + validate the request (without actually creating + the model). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_model.Model, + ) + dry_run: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class UpdateModelRequest(proto.Message): + r"""Request for updating an existing model. + + Attributes: + model (google.cloud.retail_v2alpha.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2alpha.Model]. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in the + provided 'model' to update. If not set, by + default updates all fields. + """ + + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetModelRequest(proto.Message): + r"""Request for getting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class PauseModelRequest(proto.Message): + r"""Request for pausing training of a model. + + Attributes: + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ResumeModelRequest(proto.Message): + r"""Request for resuming training of a model. + + Attributes: + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsRequest(proto.Message): + r"""Request for listing models associated with a resource. + + Attributes: + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 50. Max + allowed value is 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListModels`` call. Provide this to retrieve the subsequent + page. + """ + + 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 DeleteModelRequest(proto.Message): + r"""Request for deleting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2alpha.Model] to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsResponse(proto.Message): + r"""Response to a ListModelRequest. + + Attributes: + models (MutableSequence[google.cloud.retail_v2alpha.types.Model]): + List of Models. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + models: MutableSequence[gcr_model.Model] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class TuneModelRequest(proto.Message): + r"""Request to manually start a tuning process now (instead of + waiting for the periodically scheduled tuning to happen). + + Attributes: + name (str): + Required. The resource name of the model to tune. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateModelMetadata(proto.Message): + r"""Metadata associated with a create operation. + + Attributes: + model (str): + The resource name of the model that this create applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelMetadata(proto.Message): + r"""Metadata associated with a tune operation. + + Attributes: + model (str): + The resource name of the model that this tune applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelResponse(proto.Message): + r"""Response associated with a tune operation. + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/prediction_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/prediction_service.py new file mode 100644 index 00000000..477ee9fb --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/prediction_service.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import user_event as gcr_user_event +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'PredictRequest', + 'PredictResponse', + }, +) + + +class PredictRequest(proto.Message): + r"""Request message for Predict method. + + Attributes: + placement (str): + Required. Full resource name of the format: + ``{placement=projects/*/locations/global/catalogs/default_catalog/servingConfigs/*}`` + or + ``{placement=projects/*/locations/global/catalogs/default_catalog/placements/*}``. + We recommend using the ``servingConfigs`` resource. + ``placements`` is a legacy resource. The ID of the + Recommendations AI serving config or placement. Before you + can request predictions from your model, you must create at + least one serving config or placement for it. For more + information, see [Manage serving configs] + (https://cloud.google.com/retail/docs/manage-configs). + + The full list of available serving configs can be seen at + https://console.cloud.google.com/ai/retail/catalogs/default_catalog/configs + user_event (google.cloud.retail_v2alpha.types.UserEvent): + Required. Context about the user, what they are looking at + and what action they took to trigger the predict request. + Note that this user event detail won't be ingested to + userEvent logs. Thus, a separate userEvent write request is + required for event logging. + + Don't set + [UserEvent.visitor_id][google.cloud.retail.v2alpha.UserEvent.visitor_id] + or + [UserInfo.user_id][google.cloud.retail.v2alpha.UserInfo.user_id] + to the same fixed ID for different users. If you are trying + to receive non-personalized recommendations (not + recommended; this can negatively impact model performance), + instead set + [UserEvent.visitor_id][google.cloud.retail.v2alpha.UserEvent.visitor_id] + to a random unique ID and leave + [UserInfo.user_id][google.cloud.retail.v2alpha.UserInfo.user_id] + unset. + page_size (int): + Maximum number of results to return. Set this + property to the number of prediction results + needed. If zero, the service will choose a + reasonable default. The maximum allowed value is + 100. Values above 100 will be coerced to 100. + page_token (str): + This field is not used; leave it unset. + filter (str): + Filter for restricting prediction results with a length + limit of 5,000 characters. Accepts values for tags and the + ``filterOutOfStockItems`` flag. + + - Tag expressions. Restricts predictions to products that + match all of the specified tags. Boolean operators ``OR`` + and ``NOT`` are supported if the expression is enclosed + in parentheses, and must be separated from the tag values + by a space. ``-"tagA"`` is also supported and is + equivalent to ``NOT "tagA"``. Tag values must be double + quoted UTF-8 encoded strings with a size limit of 1,000 + characters. + + Note: "Recently viewed" models don't support tag + filtering at the moment. + + - filterOutOfStockItems. Restricts predictions to products + that do not have a stockState value of OUT_OF_STOCK. + + Examples: + + - tag=("Red" OR "Blue") tag="New-Arrival" tag=(NOT + "promotional") + - filterOutOfStockItems tag=(-"promotional") + - filterOutOfStockItems + + If your filter blocks all prediction results, the API will + return *no* results. If instead you want empty result sets + to return generic (unfiltered) popular products, set + ``strictFiltering`` to False in ``PredictRequest.params``. + Note that the API will never return items with storageStatus + of "EXPIRED" or "DELETED" regardless of filter choices. + + If ``filterSyntaxV2`` is set to true under the ``params`` + field, then attribute-based expressions are expected instead + of the above described tag-based syntax. Examples: + + - (colors: ANY("Red", "Blue")) AND NOT (categories: + ANY("Phones")) + - (availability: ANY("IN_STOCK")) AND (colors: ANY("Red") + OR categories: ANY("Phones")) + + For more information, see `Filter + recommendations `__. + validate_only (bool): + Use validate only mode for this prediction + query. If set to true, a dummy model will be + used that returns arbitrary products. Note that + the validate only mode should only be used for + testing the API, or if the model is not ready. + params (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Additional domain specific parameters for the predictions. + + Allowed values: + + - ``returnProduct``: Boolean. If set to true, the + associated product object will be returned in the + ``results.metadata`` field in the prediction response. + - ``returnScore``: Boolean. If set to true, the prediction + 'score' corresponding to each returned product will be + set in the ``results.metadata`` field in the prediction + response. The given 'score' indicates the probability of + a product being clicked/purchased given the user's + context and history. + - ``strictFiltering``: Boolean. True by default. If set to + false, the service will return generic (unfiltered) + popular products instead of empty if your filter blocks + all prediction results. + - ``priceRerankLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of + {'no-price-reranking', 'low-price-reranking', + 'medium-price-reranking', 'high-price-reranking'}. This + gives request-level control and adjusts prediction + results based on product price. + - ``diversityLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of {'no-diversity', + 'low-diversity', 'medium-diversity', 'high-diversity', + 'auto-diversity'}. This gives request-level control and + adjusts prediction results based on product category. + - ``filterSyntaxV2``: Boolean. False by default. If set to + true, the ``filter`` field is interpreteted according to + the new, attribute-based syntax. + labels (MutableMapping[str, str]): + The labels applied to a resource must meet the following + requirements: + + - Each resource can have multiple labels, up to a maximum + of 64. + - Each label must be a key-value pair. + - Keys have a minimum length of 1 character and a maximum + length of 63 characters and cannot be empty. Values can + be empty and have a maximum length of 63 characters. + - Keys and values can contain only lowercase letters, + numeric characters, underscores, and dashes. All + characters must use UTF-8 encoding, and international + characters are allowed. + - The key portion of a label must be unique. However, you + can use the same key with multiple resources. + - Keys must start with a lowercase letter or international + character. + + See `Google Cloud + Document `__ + for more details. + """ + + placement: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: gcr_user_event.UserEvent = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + filter: str = proto.Field( + proto.STRING, + number=5, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=6, + ) + params: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=struct_pb2.Value, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=8, + ) + + +class PredictResponse(proto.Message): + r"""Response message for predict method. + + Attributes: + results (MutableSequence[google.cloud.retail_v2alpha.types.PredictResponse.PredictionResult]): + A list of recommended products. The order + represents the ranking (from the most relevant + product to the least). + attribution_token (str): + A unique attribution token. This should be included in the + [UserEvent][google.cloud.retail.v2alpha.UserEvent] logs + resulting from this recommendation, which enables accurate + attribution of recommendation model performance. + missing_ids (MutableSequence[str]): + IDs of products in the request that were + missing from the inventory. + validate_only (bool): + True if the validateOnly property was set in + the request. + """ + + class PredictionResult(proto.Message): + r"""PredictionResult represents the recommendation prediction + results. + + Attributes: + id (str): + ID of the recommended product + metadata (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Additional product metadata / annotations. + + Possible values: + + - ``product``: JSON representation of the product. Is set + if ``returnProduct`` is set to true in + ``PredictRequest.params``. + - ``score``: Prediction score in double value. Is set if + ``returnScore`` is set to true in + ``PredictRequest.params``. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + metadata: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message=struct_pb2.Value, + ) + + results: MutableSequence[PredictionResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=PredictionResult, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=2, + ) + missing_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product.py new file mode 100644 index 00000000..12e542a3 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product.py @@ -0,0 +1,800 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import promotion +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'Product', + }, +) + + +class Product(proto.Message): + r"""Product captures all metadata information of items to be + recommended or searched. + + 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: + expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this product becomes unavailable for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search]. + Note that this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT]. + In general, we suggest the users to delete the stale + products explicitly, instead of using this field to + determine staleness. + + If it is set, the + [Product][google.cloud.retail.v2alpha.Product] is not + available for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + after + [expire_time][google.cloud.retail.v2alpha.Product.expire_time]. + However, the product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + [expire_time][google.cloud.retail.v2alpha.Product.expire_time] + must be later than + [available_time][google.cloud.retail.v2alpha.Product.available_time] + and + [publish_time][google.cloud.retail.v2alpha.Product.publish_time], + otherwise an INVALID_ARGUMENT error is thrown. + + Corresponding properties: Google Merchant Center property + `expiration_date `__. + + This field is a member of `oneof`_ ``expiration``. + ttl (google.protobuf.duration_pb2.Duration): + Input only. The TTL (time to live) of the product. Note that + this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT]. + In general, we suggest the users to delete the stale + products explicitly, instead of using this field to + determine staleness. + + If it is set, it must be a non-negative value, and + [expire_time][google.cloud.retail.v2alpha.Product.expire_time] + is set as current timestamp plus + [ttl][google.cloud.retail.v2alpha.Product.ttl]. The derived + [expire_time][google.cloud.retail.v2alpha.Product.expire_time] + is returned in the output and + [ttl][google.cloud.retail.v2alpha.Product.ttl] is left blank + when retrieving the + [Product][google.cloud.retail.v2alpha.Product]. + + If it is set, the product is not available for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + after current timestamp plus + [ttl][google.cloud.retail.v2alpha.Product.ttl]. However, the + product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts]. + + This field is a member of `oneof`_ ``expiration``. + name (str): + Immutable. Full resource name of the product, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/product_id``. + id (str): + Immutable. [Product][google.cloud.retail.v2alpha.Product] + identifier, which is the final component of + [name][google.cloud.retail.v2alpha.Product.name]. For + example, this field is "id_1", if + [name][google.cloud.retail.v2alpha.Product.name] is + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/id_1``. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `id `__. + Schema.org property + `Product.sku `__. + type_ (google.cloud.retail_v2alpha.types.Product.Type): + Immutable. The type of the product. Default to + [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2alpha.ProductLevelConfig.ingestion_product_type] + if unset. + primary_product_id (str): + Variant group identifier. Must be an + [id][google.cloud.retail.v2alpha.Product.id], with the same + parent branch with this product. Otherwise, an error is + thrown. + + For + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]s, this field + can only be empty or set to the same value as + [id][google.cloud.retail.v2alpha.Product.id]. + + For VARIANT [Product][google.cloud.retail.v2alpha.Product]s, + this field cannot be empty. A maximum of 2,000 products are + allowed to share the same + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]. Otherwise, + an INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `item_group_id `__. + Schema.org property + `Product.inProductGroupWithID `__. + collection_member_ids (MutableSequence[str]): + The [id][google.cloud.retail.v2alpha.Product.id] of the + collection members when + [type][google.cloud.retail.v2alpha.Product.type] is + [Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION]. + + Non-existent product ids are allowed. The + [type][google.cloud.retail.v2alpha.Product.type] of the + members must be either + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + or + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + otherwise an INVALID_ARGUMENT error is thrown. Should not + set it for other types. A maximum of 1000 values are + allowed. Otherwise, an INVALID_ARGUMENT error is return. + gtin (str): + The Global Trade Item Number (GTIN) of the product. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + This field must be a Unigram. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `gtin `__. + Schema.org property + `Product.isbn `__, + `Product.gtin8 `__, + `Product.gtin12 `__, + `Product.gtin13 `__, or + `Product.gtin14 `__. + + If the value is not a valid GTIN, an INVALID_ARGUMENT error + is returned. + categories (MutableSequence[str]): + Product categories. This field is repeated for supporting + one product belonging to several parallel categories. + Strongly recommended using the full path for better search / + recommendation quality. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + For example, if a shoes product belongs to both ["Shoes & + Accessories" -> "Shoes"] and ["Sports & Fitness" -> + "Athletic Clothing" -> "Shoes"], it could be represented as: + + :: + + "categories": [ + "Shoes & Accessories > Shoes", + "Sports & Fitness > Athletic Clothing > Shoes" + ] + + Must be set for + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product] otherwise an + INVALID_ARGUMENT error is returned. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2alpha.Product]. Empty values + are not allowed. Each value must be a UTF-8 encoded string + with a length limit of 5,000 characters. Otherwise, an + INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `google_product_category `__. + Schema.org property [Product.category] + (https://schema.org/category). + title (str): + Required. Product title. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `title `__. + Schema.org property + `Product.name `__. + brands (MutableSequence[str]): + The brands of the product. + + A maximum of 30 brands are allowed. Each brand must be a + UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `brand `__. + Schema.org property + `Product.brand `__. + description (str): + Product description. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `description `__. + Schema.org property + `Product.description `__. + language_code (str): + Language of the title/description and other string + attributes. Use language tags defined by `BCP + 47 `__. + + For product prediction, this field is ignored and the model + automatically detects the text language. The + [Product][google.cloud.retail.v2alpha.Product] can include + text in different languages, but duplicating + [Product][google.cloud.retail.v2alpha.Product]s to provide + text in multiple languages can result in degraded model + performance. + + For product search this field is in use. It defaults to + "en-US" if unset. + attributes (MutableMapping[str, google.cloud.retail_v2alpha.types.CustomAttribute]): + Highly encouraged. Extra product attributes to be included. + For example, for products, this could include the store + name, vendor, style, color, etc. These are very strong + signals for recommendation model, thus we highly recommend + providing the attributes here. + + Features that can take on one of a limited number of + possible values. Two types of features can be set are: + + Textual features. some examples would be the brand/maker of + a product, or country of a customer. Numerical features. + Some examples would be the height/weight of a product, or + age of a customer. + + For example: + ``{ "vendor": {"text": ["vendor123", "vendor456"]}, "lengths_cm": {"numbers":[2.3, 15.4]}, "heights_cm": {"numbers":[8.1, 6.4]} }``. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - Max entries count: 200. + - The key must be a UTF-8 encoded string with a length + limit of 128 characters. + - For indexable attribute, the key must match the pattern: + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, + ``key0LikeThis`` or ``KEY_1_LIKE_THIS``. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a + non-empty UTF-8 encoded string with a length limit of 256 + characters. + - For number attributes, at most 400 values are allowed. + tags (MutableSequence[str]): + Custom tags associated with the product. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2alpha.Product]. This value + must be a UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This tag can be used for filtering recommendation results by + passing the tag as part of the + [PredictRequest.filter][google.cloud.retail.v2alpha.PredictRequest.filter]. + + Corresponding properties: Google Merchant Center property + `custom_label_0–4 `__. + price_info (google.cloud.retail_v2alpha.types.PriceInfo): + Product price and cost information. + + Corresponding properties: Google Merchant Center property + `price `__. + rating (google.cloud.retail_v2alpha.types.Rating): + The rating of this product. + available_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this + [Product][google.cloud.retail.v2alpha.Product] becomes + available for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search]. + Note that this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT]. + availability (google.cloud.retail_v2alpha.types.Product.Availability): + The online availability of the + [Product][google.cloud.retail.v2alpha.Product]. Default to + [Availability.IN_STOCK][google.cloud.retail.v2alpha.Product.Availability.IN_STOCK]. + + Corresponding properties: Google Merchant Center property + `availability `__. + Schema.org property + `Offer.availability `__. + available_quantity (google.protobuf.wrappers_pb2.Int32Value): + The available quantity of the item. + fulfillment_info (MutableSequence[google.cloud.retail_v2alpha.types.FulfillmentInfo]): + Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + All the elements must have distinct + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type]. + Otherwise, an INVALID_ARGUMENT error is returned. + uri (str): + Canonical URL directly linking to the product detail page. + + It is strongly recommended to provide a valid uri for the + product, otherwise the service performance could be + significantly degraded. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `link `__. + Schema.org property `Offer.url `__. + images (MutableSequence[google.cloud.retail_v2alpha.types.Image]): + Product images for the product. We highly recommend putting + the main image first. + + A maximum of 300 images are allowed. + + Corresponding properties: Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + audience (google.cloud.retail_v2alpha.types.Audience): + The target group associated with a given + audience (e.g. male, veterans, car owners, + musicians, etc.) of the product. + color_info (google.cloud.retail_v2alpha.types.ColorInfo): + The color of the product. + + Corresponding properties: Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + sizes (MutableSequence[str]): + The size of the product. To represent different size systems + or size types, consider using this format: + [[[size_system:]size_type:]size_value]. + + For example, in "US:MENS:M", "US" represents size system; + "MENS" represents size type; "M" represents size value. In + "GIRLS:27", size system is empty; "GIRLS" represents size + type; "27" represents size value. In "32 inches", both size + system and size type are empty, while size value is "32 + inches". + + A maximum of 20 values are allowed per + [Product][google.cloud.retail.v2alpha.Product]. Each value + must be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `size `__, + `size_type `__, + and + `size_system `__. + Schema.org property + `Product.size `__. + materials (MutableSequence[str]): + The material of the product. For example, "leather", + "wooden". + + A maximum of 20 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 200 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `material `__. + Schema.org property + `Product.material `__. + patterns (MutableSequence[str]): + The pattern or graphic print of the product. For example, + "striped", "polka dot", "paisley". + + A maximum of 20 values are allowed per + [Product][google.cloud.retail.v2alpha.Product]. Each value + must be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `pattern `__. + Schema.org property + `Product.pattern `__. + conditions (MutableSequence[str]): + The condition of the product. Strongly encouraged to use the + standard values: "new", "refurbished", "used". + + A maximum of 1 value is allowed per + [Product][google.cloud.retail.v2alpha.Product]. Each value + must be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `condition `__. + Schema.org property + `Offer.itemCondition `__. + promotions (MutableSequence[google.cloud.retail_v2alpha.types.Promotion]): + The promotions applied to the product. A maximum of 10 + values are allowed per + [Product][google.cloud.retail.v2alpha.Product]. Only + [Promotion.promotion_id][google.cloud.retail.v2alpha.Promotion.promotion_id] + will be used, other fields will be ignored if set. + publish_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the product is published by the retailer + for the first time, which indicates the freshness of the + products. Note that this field is different from + [available_time][google.cloud.retail.v2alpha.Product.available_time], + given it purely describes product freshness regardless of + when it is available on search and recommendation. + retrievable_fields (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the + [Product][google.cloud.retail.v2alpha.Product]s are returned + in + [SearchResponse][google.cloud.retail.v2alpha.SearchResponse]. + + Supported fields for all + [type][google.cloud.retail.v2alpha.Product.type]s: + + - [audience][google.cloud.retail.v2alpha.Product.audience] + - [availability][google.cloud.retail.v2alpha.Product.availability] + - [brands][google.cloud.retail.v2alpha.Product.brands] + - [color_info][google.cloud.retail.v2alpha.Product.color_info] + - [conditions][google.cloud.retail.v2alpha.Product.conditions] + - [gtin][google.cloud.retail.v2alpha.Product.gtin] + - [materials][google.cloud.retail.v2alpha.Product.materials] + - [name][google.cloud.retail.v2alpha.Product.name] + - [patterns][google.cloud.retail.v2alpha.Product.patterns] + - [price_info][google.cloud.retail.v2alpha.Product.price_info] + - [rating][google.cloud.retail.v2alpha.Product.rating] + - [sizes][google.cloud.retail.v2alpha.Product.sizes] + - [title][google.cloud.retail.v2alpha.Product.title] + - [uri][google.cloud.retail.v2alpha.Product.uri] + + Supported fields only for + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION]: + + - [categories][google.cloud.retail.v2alpha.Product.categories] + - [description][google.cloud.retail.v2alpha.Product.description] + - [images][google.cloud.retail.v2alpha.Product.images] + + Supported fields only for + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT]: + + - Only the first image in + [images][google.cloud.retail.v2alpha.Product.images] + + To mark + [attributes][google.cloud.retail.v2alpha.Product.attributes] + as retrievable, include paths of the form "attributes.key" + where "key" is the key of a custom attribute, as specified + in + [attributes][google.cloud.retail.v2alpha.Product.attributes]. + + For + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION], + the following fields are always returned in + [SearchResponse][google.cloud.retail.v2alpha.SearchResponse] + by default: + + - [name][google.cloud.retail.v2alpha.Product.name] + + For + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT], + the following fields are always returned in by default: + + - [name][google.cloud.retail.v2alpha.Product.name] + - [color_info][google.cloud.retail.v2alpha.Product.color_info] + + The maximum number of paths is 30. Otherwise, an + INVALID_ARGUMENT error is returned. + + Note: Returning more fields in + [SearchResponse][google.cloud.retail.v2alpha.SearchResponse] + can increase response payload size and serving latency. + + This field is deprecated. Use the retrievable site-wide + control instead. + variants (MutableSequence[google.cloud.retail_v2alpha.types.Product]): + Output only. Product variants grouped together on primary + product which share similar product attributes. It's + automatically grouped by + [primary_product_id][google.cloud.retail.v2alpha.Product.primary_product_id] + for all the product variants. Only populated for + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct]. + Do not set this field in API requests. + local_inventories (MutableSequence[google.cloud.retail_v2alpha.types.LocalInventory]): + Output only. A list of local inventories specific to + different places. + + This field can be managed by + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + and + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + APIs if fine-grained, high-volume updates are necessary. + """ + class Type(proto.Enum): + r"""The type of this product. + + Values: + TYPE_UNSPECIFIED (0): + Default value. Default to + [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2alpha.ProductLevelConfig.ingestion_product_type] + if unset. + PRIMARY (1): + The primary type. + + As the primary unit for predicting, indexing and search + serving, a + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product] is grouped + with multiple + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s. + VARIANT (2): + The variant type. + + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s usually + share some common attributes on the same + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]s, but they + have variant attributes like different colors, sizes and + prices, etc. + COLLECTION (3): + The collection type. Collection products are bundled + [Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]s or + [Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s that are + sold together, such as a jewelry set with necklaces, + earrings and rings, etc. + """ + TYPE_UNSPECIFIED = 0 + PRIMARY = 1 + VARIANT = 2 + COLLECTION = 3 + + class Availability(proto.Enum): + r"""Product availability. If this field is unspecified, the + product is assumed to be in stock. + + Values: + AVAILABILITY_UNSPECIFIED (0): + Default product availability. Default to + [Availability.IN_STOCK][google.cloud.retail.v2alpha.Product.Availability.IN_STOCK] + if unset. + IN_STOCK (1): + Product in stock. + OUT_OF_STOCK (2): + Product out of stock. + PREORDER (3): + Product that is in pre-order state. + BACKORDER (4): + Product that is back-ordered (i.e. + temporarily out of stock). + """ + AVAILABILITY_UNSPECIFIED = 0 + IN_STOCK = 1 + OUT_OF_STOCK = 2 + PREORDER = 3 + BACKORDER = 4 + + expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=16, + oneof='expiration', + message=timestamp_pb2.Timestamp, + ) + ttl: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=17, + oneof='expiration', + message=duration_pb2.Duration, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + type_: Type = proto.Field( + proto.ENUM, + number=3, + enum=Type, + ) + primary_product_id: str = proto.Field( + proto.STRING, + number=4, + ) + collection_member_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + gtin: str = proto.Field( + proto.STRING, + number=6, + ) + categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + title: str = proto.Field( + proto.STRING, + number=8, + ) + brands: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + description: str = proto.Field( + proto.STRING, + number=10, + ) + language_code: str = proto.Field( + proto.STRING, + number=11, + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=12, + message=common.CustomAttribute, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + price_info: common.PriceInfo = proto.Field( + proto.MESSAGE, + number=14, + message=common.PriceInfo, + ) + rating: common.Rating = proto.Field( + proto.MESSAGE, + number=15, + message=common.Rating, + ) + available_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=18, + message=timestamp_pb2.Timestamp, + ) + availability: Availability = proto.Field( + proto.ENUM, + number=19, + enum=Availability, + ) + available_quantity: wrappers_pb2.Int32Value = proto.Field( + proto.MESSAGE, + number=20, + message=wrappers_pb2.Int32Value, + ) + fulfillment_info: MutableSequence[common.FulfillmentInfo] = proto.RepeatedField( + proto.MESSAGE, + number=21, + message=common.FulfillmentInfo, + ) + uri: str = proto.Field( + proto.STRING, + number=22, + ) + images: MutableSequence[common.Image] = proto.RepeatedField( + proto.MESSAGE, + number=23, + message=common.Image, + ) + audience: common.Audience = proto.Field( + proto.MESSAGE, + number=24, + message=common.Audience, + ) + color_info: common.ColorInfo = proto.Field( + proto.MESSAGE, + number=25, + message=common.ColorInfo, + ) + sizes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=26, + ) + materials: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=27, + ) + patterns: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=28, + ) + conditions: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=29, + ) + promotions: MutableSequence[promotion.Promotion] = proto.RepeatedField( + proto.MESSAGE, + number=34, + message=promotion.Promotion, + ) + publish_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=33, + message=timestamp_pb2.Timestamp, + ) + retrievable_fields: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=30, + message=field_mask_pb2.FieldMask, + ) + variants: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=31, + message='Product', + ) + local_inventories: MutableSequence[common.LocalInventory] = proto.RepeatedField( + proto.MESSAGE, + number=35, + message=common.LocalInventory, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product_service.py new file mode 100644 index 00000000..4c321e48 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/product_service.py @@ -0,0 +1,939 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'CreateProductRequest', + 'GetProductRequest', + 'UpdateProductRequest', + 'DeleteProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'SetInventoryRequest', + 'SetInventoryMetadata', + 'SetInventoryResponse', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesResponse', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesResponse', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesResponse', + }, +) + + +class CreateProductRequest(proto.Message): + r"""Request message for + [ProductService.CreateProduct][google.cloud.retail.v2alpha.ProductService.CreateProduct] + method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + product (google.cloud.retail_v2alpha.types.Product): + Required. The [Product][google.cloud.retail.v2alpha.Product] + to create. + product_id (str): + Required. The ID to use for the + [Product][google.cloud.retail.v2alpha.Product], which will + become the final component of the + [Product.name][google.cloud.retail.v2alpha.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2alpha.Product]s with the + same + [parent][google.cloud.retail.v2alpha.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + product_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetProductRequest(proto.Message): + r"""Request message for + [ProductService.GetProduct][google.cloud.retail.v2alpha.ProductService.GetProduct] + method. + + Attributes: + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the requested + [Product][google.cloud.retail.v2alpha.Product] does not + exist, a NOT_FOUND error is returned. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductRequest(proto.Message): + r"""Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + method. + + Attributes: + product (google.cloud.retail_v2alpha.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2alpha.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Product][google.cloud.retail.v2alpha.Product] to update. + The immutable and output only fields are NOT supported. If + not set, all supported fields (the fields that are neither + immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask path as + "attributes.${key_name}". If a key name is present in the + mask but not in the patching product from the request, this + key will be deleted after the update. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2alpha.Product] is not found, + a new [Product][google.cloud.retail.v2alpha.Product] will be + created. In this situation, ``update_mask`` is ignored. + """ + + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class DeleteProductRequest(proto.Message): + r"""Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2alpha.ProductService.DeleteProduct] + method. + + Attributes: + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2alpha.Product] to delete + can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2alpha.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product] with more + than one + [variants][google.cloud.retail.v2alpha.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2alpha.Product] will be + deleted. + force (bool): + This value only applies to the case when the + target product is of type PRIMARY. + When deleting a product of VARIANT/COLLECTION + type, this value will be ignored. + When set to true, the subsequent variant + products will be deleted. + When set to false, if the primary product has + active variant products, an error will be + returned. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + force: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class ListProductsRequest(proto.Message): + r"""Request message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + method. + + Attributes: + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list products + under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2alpha.Product]s under this + branch, regardless of whether or not this branch exists, a + PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of + [Product][google.cloud.retail.v2alpha.Product]s to return. + If unspecified, defaults to 100. The maximum allowed value + is 1000. Values above 1000 will be coerced to 1000. + + If this field is negative, an INVALID_ARGUMENT error is + returned. + page_token (str): + A page token + [ListProductsResponse.next_page_token][google.cloud.retail.v2alpha.ListProductsResponse.next_page_token], + received from a previous + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + filter (str): + A filter to apply on the list results. Supported features: + + - List all the products under the parent branch if + [filter][google.cloud.retail.v2alpha.ListProductsRequest.filter] + is unset. + - List + [Product.Type.VARIANT][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s sharing + the same + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product]. For + example: ``primary_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2alpha.Product]s + bundled in a + [Product.Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2alpha.Product]. For + example: ``collection_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2alpha.Product]s with + a partibular type. For example: ``type = "PRIMARY"`` + ``type = "VARIANT"`` ``type = "COLLECTION"`` + + If the field is unrecognizable, an INVALID_ARGUMENT error is + returned. + + If the specified + [Product.Type.PRIMARY][google.cloud.retail.v2alpha.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2alpha.Product] or + [Product.Type.COLLECTION][google.cloud.retail.v2alpha.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2alpha.Product] does not + exist, a NOT_FOUND error is returned. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields of [Product][google.cloud.retail.v2alpha.Product] + to return in the responses. If not set or empty, the + following fields are returned: + + - [Product.name][google.cloud.retail.v2alpha.Product.name] + - [Product.id][google.cloud.retail.v2alpha.Product.id] + - [Product.title][google.cloud.retail.v2alpha.Product.title] + - [Product.uri][google.cloud.retail.v2alpha.Product.uri] + - [Product.images][google.cloud.retail.v2alpha.Product.images] + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + - [Product.brands][google.cloud.retail.v2alpha.Product.brands] + + If "*" is provided, all fields are returned. + [Product.name][google.cloud.retail.v2alpha.Product.name] is + always returned no matter what mask is set. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + require_total_size (bool): + If true and + [page_token][google.cloud.retail.v2alpha.ListProductsRequest.page_token] + is empty, + [ListProductsResponse.total_size][google.cloud.retail.v2alpha.ListProductsResponse.total_size] + is set to the total count of matched items irrespective of + pagination. + + Notice that setting this field to true affects the + performance. + """ + + 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, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + read_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=5, + message=field_mask_pb2.FieldMask, + ) + require_total_size: bool = proto.Field( + proto.BOOL, + number=6, + ) + + +class ListProductsResponse(proto.Message): + r"""Response message for + [ProductService.ListProducts][google.cloud.retail.v2alpha.ProductService.ListProducts] + method. + + Attributes: + products (MutableSequence[google.cloud.retail_v2alpha.types.Product]): + The [Product][google.cloud.retail.v2alpha.Product]s. + next_page_token (str): + A token that can be sent as + [ListProductsRequest.page_token][google.cloud.retail.v2alpha.ListProductsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + total_size (int): + The total count of matched + [Product][google.cloud.retail.v2alpha.Product]s irrespective + of pagination. The total number of + [Product][google.cloud.retail.v2alpha.Product]s returned by + pagination may be less than the + [total_size][google.cloud.retail.v2alpha.ListProductsResponse.total_size] + that matches. + + This field is ignored if + [ListProductsRequest.require_total_size][google.cloud.retail.v2alpha.ListProductsRequest.require_total_size] + is not set or + [ListProductsRequest.page_token][google.cloud.retail.v2alpha.ListProductsRequest.page_token] + is not empty. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence[gcr_product.Product] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + + +class SetInventoryRequest(proto.Message): + r"""Request message for + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + method. + + Attributes: + inventory (google.cloud.retail_v2alpha.types.Product): + Required. The inventory information to update. The allowable + fields to update are: + + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + - [Product.availability][google.cloud.retail.v2alpha.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2alpha.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2alpha.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2alpha.Product] named in + [Product.name][google.cloud.retail.v2alpha.Product.name], + regardless of whether or not it exists, a PERMISSION_DENIED + error is returned. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2alpha.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting the + last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2alpha.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of fulfillment + types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2alpha.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + - Checks that only the desired fulfillment info types have + empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + + The last update time is recorded for the following inventory + fields: + + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + - [Product.availability][google.cloud.retail.v2alpha.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2alpha.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2alpha.Product.fulfillment_info] + + If a full overwrite of inventory information while ignoring + timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2alpha.ProductService.UpdateProduct] + should be invoked instead. + set_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2alpha.Product] to update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the request is issued, used to + prevent out-of-order updates on inventory fields + with the last update time recorded. If not + provided, the internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2alpha.Product] with name + [Product.name][google.cloud.retail.v2alpha.Product.name] is + not found, the inventory update will still be processed and + retained for at most 1 day until the + [Product][google.cloud.retail.v2alpha.Product] is created. + If set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2alpha.Product] is not found. + """ + + inventory: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + set_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + set_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class SetInventoryMetadata(proto.Message): + r"""Metadata related to the progress of the SetInventory operation. + Currently empty because there is no meaningful metadata populated + from the + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + method. + + """ + + +class SetInventoryResponse(proto.Message): + r"""Response of the SetInventoryRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2alpha.ProductService.SetInventory] + method. + + """ + + +class AddFulfillmentPlacesRequest(proto.Message): + r"""Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + This field directly corresponds to + [Product.fulfillment_info.type][google.cloud.retail.v2alpha.FulfillmentInfo.type]. + place_ids (MutableSequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2alpha.AddFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery" to be added for this + [type][google.cloud.retail.v2alpha.AddFulfillmentPlacesRequest.type]. + Duplicate IDs will be automatically ignored. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + + If the total number of place IDs exceeds 2000 for this + [type][google.cloud.retail.v2alpha.AddFulfillmentPlacesRequest.type] + after adding, then the update will be rejected. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2alpha.Product] is not found, + the fulfillment information will still be processed and + retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2alpha.Product] is created. + If set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2alpha.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + type_: str = proto.Field( + proto.STRING, + number=2, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + add_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class AddFulfillmentPlacesMetadata(proto.Message): + r"""Metadata related to the progress of the AddFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + method. + + """ + + +class AddFulfillmentPlacesResponse(proto.Message): + r"""Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces] + method. + + """ + + +class AddLocalInventoriesRequest(proto.Message): + r"""Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + local_inventories (MutableSequence[google.cloud.retail_v2alpha.types.LocalInventory]): + Required. A list of inventory information at + difference places. Each place is identified by + its place ID. At most 3000 inventories are + allowed per request. + add_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided list of + [LocalInventory][google.cloud.retail.v2alpha.LocalInventory] + to update. The field is updated to the provided value. + + If a field is set while the place does not have a previous + local inventory, the local inventory at that store is + created. + + If a field is set while the value of that field is not + provided, the original field value, if it exists, is + deleted. + + If the mask is not set or set with empty paths, all + inventory fields will be updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory updates are + issued. Used to prevent out-of-order updates on + local inventory fields. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2alpha.Product] is not found, + the local inventory will still be processed and retained for + at most 1 day and processed once the + [Product][google.cloud.retail.v2alpha.Product] is created. + If set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2alpha.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + local_inventories: MutableSequence[common.LocalInventory] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.LocalInventory, + ) + add_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + add_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=6, + ) + + +class AddLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the AddLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method. + + """ + + +class AddLocalInventoriesResponse(proto.Message): + r"""Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful response + populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2alpha.ProductService.AddLocalInventories] + method. + + """ + + +class RemoveLocalInventoriesRequest(proto.Message): + r"""Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + place_ids (MutableSequence[str]): + Required. A list of place IDs to have their + inventory deleted. At most 3000 place IDs are + allowed per request. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory deletions are + issued. Used to prevent out-of-order updates and + deletions on local inventory fields. If not + provided, the internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2alpha.Product] is not found, + the local inventory removal request will still be processed + and retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2alpha.Product] is created. + If set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2alpha.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + remove_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class RemoveLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the RemoveLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method. + + """ + + +class RemoveLocalInventoriesResponse(proto.Message): + r"""Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful response + populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories] + method. + + """ + + +class RemoveFulfillmentPlacesRequest(proto.Message): + r"""Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2alpha.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2alpha.Product], regardless + of whether or not it exists, a PERMISSION_DENIED error is + returned. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + This field directly corresponds to + [Product.fulfillment_info.type][google.cloud.retail.v2alpha.FulfillmentInfo.type]. + place_ids (MutableSequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2alpha.RemoveFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery", to be removed for this + [type][google.cloud.retail.v2alpha.RemoveFulfillmentPlacesRequest.type]. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2alpha.Product] is not found, + the fulfillment information will still be processed and + retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2alpha.Product] is created. + If set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2alpha.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + type_: str = proto.Field( + proto.STRING, + number=2, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + remove_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class RemoveFulfillmentPlacesMetadata(proto.Message): + r"""Metadata related to the progress of the RemoveFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + method. + + """ + + +class RemoveFulfillmentPlacesResponse(proto.Message): + r"""Response of the RemoveFulfillmentPlacesRequest. Currently empty + because there is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces] + method. + + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/promotion.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/promotion.py new file mode 100644 index 00000000..332907fc --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/promotion.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail.v2alpha', + manifest={ + 'Promotion', + }, +) + + +class Promotion(proto.Message): + r"""Promotion information. + + Attributes: + promotion_id (str): + ID of the promotion. For example, "free gift". + + The value must be a UTF-8 encoded string with a length limit + of 128 characters, and match the pattern: + ``[a-zA-Z][a-zA-Z0-9_]*``. For example, id0LikeThis or + ID_1_LIKE_THIS. Otherwise, an INVALID_ARGUMENT error is + returned. + + Google Merchant Center property + `promotion `__. + """ + + promotion_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/purge_config.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/purge_config.py new file mode 100644 index 00000000..a93a6574 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/purge_config.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'PurgeMetadata', + 'PurgeProductsMetadata', + 'PurgeProductsRequest', + 'PurgeProductsResponse', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + }, +) + + +class PurgeMetadata(proto.Message): + r"""Metadata related to the progress of the Purge operation. + This will be returned by the + google.longrunning.Operation.metadata field. + + """ + + +class PurgeProductsMetadata(proto.Message): + r"""Metadata related to the progress of the PurgeProducts + operation. This will be returned by the + google.longrunning.Operation.metadata field. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + success_count (int): + Count of entries that were deleted + successfully. + failure_count (int): + Count of entries that encountered errors + while processing. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + success_count: int = proto.Field( + proto.INT64, + number=3, + ) + failure_count: int = proto.Field( + proto.INT64, + number=4, + ) + + +class PurgeProductsRequest(proto.Message): + r"""Request message for PurgeProducts method. + + Attributes: + parent (str): + Required. The resource name of the branch under which the + products are created. The format is + ``projects/${projectId}/locations/global/catalogs/${catalogId}/branches/${branchId}`` + filter (str): + Required. The filter string to specify the products to be + deleted with a length limit of 5,000 characters. + + Empty string filter is not allowed. "*" implies delete all + items in a branch. + + The eligible fields for filtering are: + + - ``availability``: Double quoted + [Product.availability][google.cloud.retail.v2alpha.Product.availability] + string. + - ``create_time`` : in ISO 8601 "zulu" format. + + Supported syntax: + + - Comparators (">", "<", ">=", "<=", "="). Examples: + + - create_time <= "2015-02-13T17:05:46Z" + - availability = "IN_STOCK" + + - Conjunctions ("AND") Examples: + + - create_time <= "2015-02-13T17:05:46Z" AND availability + = "PREORDER" + + - Disjunctions ("OR") Examples: + + - create_time <= "2015-02-13T17:05:46Z" OR availability + = "IN_STOCK" + + - Can support nested queries. Examples: + + - (create_time <= "2015-02-13T17:05:46Z" AND + availability = "PREORDER") OR (create_time >= + "2015-02-14T13:03:32Z" AND availability = "IN_STOCK") + + - Filter Limits: + + - Filter should not contain more than 6 conditions. + - Max nesting depth should not exceed 2 levels. + + Examples queries: + + - Delete back order products created before a timestamp. + create_time <= "2015-02-13T17:05:46Z" OR availability = + "BACKORDER". + force (bool): + Actually perform the purge. If ``force`` is set to false, + the method will return the expected purge count without + deleting any products. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + force: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class PurgeProductsResponse(proto.Message): + r"""Response of the PurgeProductsRequest. If the long running + operation is successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + Attributes: + purge_count (int): + The total count of products purged as a + result of the operation. + purge_sample (MutableSequence[str]): + A sample of the product names that will be deleted. Only + populated if ``force`` is set to false. A max of 100 names + will be returned and the names are chosen at random. + """ + + purge_count: int = proto.Field( + proto.INT64, + number=1, + ) + purge_sample: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class PurgeUserEventsRequest(proto.Message): + r"""Request message for PurgeUserEvents method. + + Attributes: + parent (str): + Required. The resource name of the catalog under which the + events are created. The format is + ``projects/${projectId}/locations/global/catalogs/${catalogId}`` + filter (str): + Required. The filter string to specify the events to be + deleted with a length limit of 5,000 characters. Empty + string filter is not allowed. The eligible fields for + filtering are: + + - ``eventType``: Double quoted + [UserEvent.event_type][google.cloud.retail.v2alpha.UserEvent.event_type] + string. + - ``eventTime``: in ISO 8601 "zulu" format. + - ``visitorId``: Double quoted string. Specifying this will + delete all events associated with a visitor. + - ``userId``: Double quoted string. Specifying this will + delete all events associated with a user. + + Examples: + + - Deleting all events in a time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventTime < "2012-04-23T18:30:43.511Z"`` + - Deleting specific eventType in time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventType = "detail-page-view"`` + - Deleting all events for a specific visitor: + ``visitorId = "visitor1024"`` + + The filtering fields are assumed to have an implicit AND. + force (bool): + Actually perform the purge. If ``force`` is set to false, + the method will return the expected purge count without + deleting any user events. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + force: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class PurgeUserEventsResponse(proto.Message): + r"""Response of the PurgeUserEventsRequest. If the long running + operation is successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + Attributes: + purged_events_count (int): + The total count of events purged as a result + of the operation. + """ + + purged_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/search_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/search_service.py new file mode 100644 index 00000000..f025c604 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/search_service.py @@ -0,0 +1,1456 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'SearchRequest', + 'SearchResponse', + 'ExperimentInfo', + }, +) + + +class SearchRequest(proto.Message): + r"""Request message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + method. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + placement (str): + Required. The resource name of the Retail Search serving + config, such as + ``projects/*/locations/global/catalogs/default_catalog/servingConfigs/default_serving_config`` + or the name of the legacy placement resource, such as + ``projects/*/locations/global/catalogs/default_catalog/placements/default_search``. + This field is used to identify the serving config name and + the set of models that will be used to make the search. + branch (str): + The branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + + Use "default_branch" as the branch ID or leave this field + empty, to search products under the default branch. + query (str): + Raw search query. + + If this field is empty, the request is considered a category + browsing request and returned results are based on + [filter][google.cloud.retail.v2alpha.SearchRequest.filter] + and + [page_categories][google.cloud.retail.v2alpha.SearchRequest.page_categories]. + visitor_id (str): + Required. A unique identifier for tracking visitors. For + example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor logs in or out of the website. + + This should be the same identifier as + [UserEvent.visitor_id][google.cloud.retail.v2alpha.UserEvent.visitor_id]. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + user_info (google.cloud.retail_v2alpha.types.UserInfo): + User information. + page_size (int): + Maximum number of + [Product][google.cloud.retail.v2alpha.Product]s to return. + If unspecified, defaults to a reasonable value. The maximum + allowed value is 120. Values above 120 will be coerced to + 120. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [SearchResponse.next_page_token][google.cloud.retail.v2alpha.SearchResponse.next_page_token], + received from a previous + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + offset (int): + A 0-indexed integer that specifies the current offset (that + is, starting result location, amongst the + [Product][google.cloud.retail.v2alpha.Product]s deemed by + the API as relevant) in search results. This field is only + considered if + [page_token][google.cloud.retail.v2alpha.SearchRequest.page_token] + is unset. + + If this field is negative, an INVALID_ARGUMENT is returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. Filter expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + canonical_filter (str): + The default filter that is applied when a user performs a + search without checking any filters on the search page. + + The filter applied to every search request when quality + improvement such as query expansion is needed. For example, + if a query does not have enough results, an expanded query + with + [SearchRequest.canonical_filter][google.cloud.retail.v2alpha.SearchRequest.canonical_filter] + will be returned as a supplement of the original query. This + field is strongly recommended to achieve high search + quality. + + See + [SearchRequest.filter][google.cloud.retail.v2alpha.SearchRequest.filter] + for more details about filter syntax. + order_by (str): + The order in which products are returned. Products can be + ordered by a field in an + [Product][google.cloud.retail.v2alpha.Product] object. Leave + it unset if ordered by relevance. OrderBy expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + facet_specs (MutableSequence[google.cloud.retail_v2alpha.types.SearchRequest.FacetSpec]): + Facet specifications for faceted search. If empty, no facets + are returned. + + A maximum of 200 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + dynamic_facet_spec (google.cloud.retail_v2alpha.types.SearchRequest.DynamicFacetSpec): + Deprecated. Refer to + https://cloud.google.com/retail/docs/configs#dynamic + to enable dynamic facets. Do not set this field. + + The specification for dynamically generated + facets. Notice that only textual facets can be + dynamically generated. + boost_spec (google.cloud.retail_v2alpha.types.SearchRequest.BoostSpec): + Boost specification to boost certain products. See more + details at this `user + guide `__. + + Notice that if both + [ServingConfig.boost_control_ids][google.cloud.retail.v2alpha.ServingConfig.boost_control_ids] + and + [SearchRequest.boost_spec][google.cloud.retail.v2alpha.SearchRequest.boost_spec] + are set, the boost conditions from both places are + evaluated. If a search request matches multiple boost + conditions, the final boost score is equal to the sum of the + boost scores from all matched boost conditions. + query_expansion_spec (google.cloud.retail_v2alpha.types.SearchRequest.QueryExpansionSpec): + The query expansion specification that specifies the + conditions under which query expansion will occur. See more + details at this `user + guide `__. + relevance_threshold (google.cloud.retail_v2alpha.types.SearchRequest.RelevanceThreshold): + The relevance threshold of the search results. + + Defaults to + [RelevanceThreshold.HIGH][google.cloud.retail.v2alpha.SearchRequest.RelevanceThreshold.HIGH], + which means only the most relevant results are shown, and + the least number of results are returned. See more details + at this `user + guide `__. + variant_rollup_keys (MutableSequence[str]): + The keys to fetch and rollup the matching + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s attributes, + [FulfillmentInfo][google.cloud.retail.v2alpha.FulfillmentInfo] + or + [LocalInventory][google.cloud.retail.v2alpha.LocalInventory]s + attributes. The attributes from all the matching + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s or + [LocalInventory][google.cloud.retail.v2alpha.LocalInventory]s + are merged and de-duplicated. Notice that rollup attributes + will lead to extra query latency. Maximum number of keys is + 30. + + For + [FulfillmentInfo][google.cloud.retail.v2alpha.FulfillmentInfo], + a fulfillment type and a fulfillment ID must be provided in + the format of "fulfillmentType.fulfillmentId". E.g., in + "pickupInStore.store123", "pickupInStore" is fulfillment + type and "store123" is the store ID. + + Supported keys are: + + - colorFamilies + - price + - originalPrice + - discount + - variantId + - inventory(place_id,price) + - inventory(place_id,original_price) + - inventory(place_id,attributes.key), where key is any key + in the + [Product.local_inventories.attributes][google.cloud.retail.v2alpha.LocalInventory.attributes] + map. + - attributes.key, where key is any key in the + [Product.attributes][google.cloud.retail.v2alpha.Product.attributes] + map. + - pickupInStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "pickup-in-store". + - shipToStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "ship-to-store". + - sameDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "same-day-delivery". + - nextDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "next-day-delivery". + - customFulfillment1.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "custom-type-1". + - customFulfillment2.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "custom-type-2". + - customFulfillment3.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "custom-type-3". + - customFulfillment4.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "custom-type-4". + - customFulfillment5.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2alpha.FulfillmentInfo.type] + "custom-type-5". + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + page_categories (MutableSequence[str]): + The categories associated with a category page. Must be set + for category navigation queries to achieve good search + quality. The format should be the same as + [UserEvent.page_categories][google.cloud.retail.v2alpha.UserEvent.page_categories]; + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + search_mode (google.cloud.retail_v2alpha.types.SearchRequest.SearchMode): + The search mode of the search request. If not + specified, a single search request triggers both + product search and faceted search. + personalization_spec (google.cloud.retail_v2alpha.types.SearchRequest.PersonalizationSpec): + The specification for personalization. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2alpha.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2alpha.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2alpha.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2alpha.ServingConfig.personalization_spec]. + labels (MutableMapping[str, str]): + The labels applied to a resource must meet the following + requirements: + + - Each resource can have multiple labels, up to a maximum + of 64. + - Each label must be a key-value pair. + - Keys have a minimum length of 1 character and a maximum + length of 63 characters and cannot be empty. Values can + be empty and have a maximum length of 63 characters. + - Keys and values can contain only lowercase letters, + numeric characters, underscores, and dashes. All + characters must use UTF-8 encoding, and international + characters are allowed. + - The key portion of a label must be unique. However, you + can use the same key with multiple resources. + - Keys must start with a lowercase letter or international + character. + + See `Google Cloud + Document `__ + for more details. + spell_correction_spec (google.cloud.retail_v2alpha.types.SearchRequest.SpellCorrectionSpec): + The spell correction specification that + specifies the mode under which spell correction + will take effect. + + This field is a member of `oneof`_ ``_spell_correction_spec``. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2alpha.UserEvent.entity] + to get search results boosted by entity. + """ + class RelevanceThreshold(proto.Enum): + r"""The relevance threshold of the search results. The higher + relevance threshold is, the higher relevant results are shown + and the less number of results are returned. + + Values: + RELEVANCE_THRESHOLD_UNSPECIFIED (0): + Default value. In this case, server behavior defaults to + [RelevanceThreshold.HIGH][google.cloud.retail.v2alpha.SearchRequest.RelevanceThreshold.HIGH]. + HIGH (1): + High relevance threshold. + MEDIUM (2): + Medium relevance threshold. + LOW (3): + Low relevance threshold. + LOWEST (4): + Lowest relevance threshold. + """ + RELEVANCE_THRESHOLD_UNSPECIFIED = 0 + HIGH = 1 + MEDIUM = 2 + LOW = 3 + LOWEST = 4 + + class SearchMode(proto.Enum): + r"""The search mode of each search request. + + Values: + SEARCH_MODE_UNSPECIFIED (0): + Default value. In this case both product search and faceted + search will be performed. Both + [SearchResponse.SearchResult][google.cloud.retail.v2alpha.SearchResponse.SearchResult] + and + [SearchResponse.Facet][google.cloud.retail.v2alpha.SearchResponse.Facet] + will be returned. + PRODUCT_SEARCH_ONLY (1): + Only product search will be performed. The faceted search + will be disabled. + + Only + [SearchResponse.SearchResult][google.cloud.retail.v2alpha.SearchResponse.SearchResult] + will be returned. + [SearchResponse.Facet][google.cloud.retail.v2alpha.SearchResponse.Facet] + will not be returned, even if + [SearchRequest.facet_specs][google.cloud.retail.v2alpha.SearchRequest.facet_specs] + or + [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2alpha.SearchRequest.dynamic_facet_spec] + is set. + FACETED_SEARCH_ONLY (2): + Only faceted search will be performed. The product search + will be disabled. + + When in this mode, one or both of + [SearchRequest.facet_specs][google.cloud.retail.v2alpha.SearchRequest.facet_specs] + and + [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2alpha.SearchRequest.dynamic_facet_spec] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. Only + [SearchResponse.Facet][google.cloud.retail.v2alpha.SearchResponse.Facet] + will be returned. + [SearchResponse.SearchResult][google.cloud.retail.v2alpha.SearchResponse.SearchResult] + will not be returned. + """ + SEARCH_MODE_UNSPECIFIED = 0 + PRODUCT_SEARCH_ONLY = 1 + FACETED_SEARCH_ONLY = 2 + + class FacetSpec(proto.Message): + r"""A facet specification to perform faceted search. + + Attributes: + facet_key (google.cloud.retail_v2alpha.types.SearchRequest.FacetSpec.FacetKey): + Required. The facet key specification. + limit (int): + Maximum of facet values that should be returned for this + facet. If unspecified, defaults to 50. The maximum allowed + value is 300. Values above 300 will be coerced to 300. + + If this field is negative, an INVALID_ARGUMENT is returned. + excluded_filter_keys (MutableSequence[str]): + List of keys to exclude when faceting. + + By default, + [FacetKey.key][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.key] + is not excluded from the filter unless it is listed in this + field. + + Listing a facet key in this field allows its values to + appear as facet results, even when they are filtered out of + search results. Using this field does not affect what search + results are returned. + + For example, suppose there are 100 products with the color + facet "Red" and 200 products with the color facet "Blue". A + query containing the filter "colorFamilies:ANY("Red")" and + having "colorFamilies" as + [FacetKey.key][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.key] + would by default return only "Red" products in the search + results, and also return "Red" with count 100 as the only + color facet. Although there are also blue products + available, "Blue" would not be shown as an available facet + value. + + If "colorFamilies" is listed in "excludedFilterKeys", then + the query returns the facet values "Red" with count 100 and + "Blue" with count 200, because the "colorFamilies" key is + now excluded from the filter. Because this field doesn't + affect search results, the search results are still + correctly filtered to return only "Red" products. + + A maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + enable_dynamic_position (bool): + Enables dynamic position for this facet. If set to true, the + position of this facet among all facets in the response is + determined by Google Retail Search. It will be ordered + together with dynamic facets if dynamic facets is enabled. + If set to false, the position of this facet in the response + will be the same as in the request, and it will be ranked + before the facets with dynamic position enable and all + dynamic facets. + + For example, you may always want to have rating facet + returned in the response, but it's not necessarily to always + display the rating facet at the top. In that case, you can + set enable_dynamic_position to true so that the position of + rating facet in response will be determined by Google Retail + Search. + + Another example, assuming you have the following facets in + the request: + + - "rating", enable_dynamic_position = true + + - "price", enable_dynamic_position = false + + - "brands", enable_dynamic_position = false + + And also you have a dynamic facets enable, which will + generate a facet 'gender'. Then the final order of the + facets in the response can be ("price", "brands", "rating", + "gender") or ("price", "brands", "gender", "rating") depends + on how Google Retail Search orders "gender" and "rating" + facets. However, notice that "price" and "brands" will + always be ranked at 1st and 2nd position since their + enable_dynamic_position are false. + """ + + class FacetKey(proto.Message): + r"""Specifies how a facet is computed. + + Attributes: + key (str): + Required. Supported textual and numerical facet keys in + [Product][google.cloud.retail.v2alpha.Product] object, over + which the facet values are computed. Facet key is + case-sensitive. + + Allowed facet keys when + [FacetKey.query][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.query] + is not specified: + + - textual_field = + + - "brands" + - "categories" + - "genders" + - "ageGroups" + - "availability" + - "colorFamilies" + - "colors" + - "sizes" + - "materials" + - "patterns" + - "conditions" + - "attributes.key" + - "pickupInStore" + - "shipToStore" + - "sameDayDelivery" + - "nextDayDelivery" + - "customFulfillment1" + - "customFulfillment2" + - "customFulfillment3" + - "customFulfillment4" + - "customFulfillment5" + - "inventory(place_id,attributes.key)" + + - numerical_field = + + - "price" + - "discount" + - "rating" + - "ratingCount" + - "attributes.key" + - "inventory(place_id,price)" + - "inventory(place_id,original_price)" + - "inventory(place_id,attributes.key)". + intervals (MutableSequence[google.cloud.retail_v2alpha.types.Interval]): + Set only if values should be bucketized into + intervals. Must be set for facets with numerical + values. Must not be set for facet with text + values. Maximum number of intervals is 40. + + For all numerical facet keys that appear in the + list of products from the catalog, the + percentiles 0, 10, 30, 50, 70, 90 and 100 are + computed from their distribution weekly. If the + model assigns a high score to a numerical facet + key and its intervals are not specified in the + search request, these percentiles will become + the bounds for its intervals and will be + returned in the response. If the facet key + intervals are specified in the request, then the + specified intervals will be returned instead. + restricted_values (MutableSequence[str]): + Only get facet for the given restricted values. For example, + when using "pickupInStore" as key and set restricted values + to ["store123", "store456"], only facets for "store123" and + "store456" are returned. Only supported on predefined + textual fields, custom textual attributes and fulfillments. + Maximum is 20. + + Must be set for the fulfillment facet keys: + + - pickupInStore + + - shipToStore + + - sameDayDelivery + + - nextDayDelivery + + - customFulfillment1 + + - customFulfillment2 + + - customFulfillment3 + + - customFulfillment4 + + - customFulfillment5 + prefixes (MutableSequence[str]): + Only get facet values that start with the + given string prefix. For example, suppose + "categories" has three values "Women > Shoe", + "Women > Dress" and "Men > Shoe". If set + "prefixes" to "Women", the "categories" facet + will give only "Women > Shoe" and "Women > + Dress". Only supported on textual fields. + Maximum is 10. + contains (MutableSequence[str]): + Only get facet values that contains the given + strings. For example, suppose "categories" has + three values "Women > Shoe", "Women > Dress" and + "Men > Shoe". If set "contains" to "Shoe", the + "categories" facet will give only "Women > Shoe" + and "Men > Shoe". Only supported on textual + fields. Maximum is 10. + case_insensitive (bool): + True to make facet keys case insensitive when + getting faceting values with prefixes or + contains; false otherwise. + order_by (str): + The order in which + [SearchResponse.Facet.values][google.cloud.retail.v2alpha.SearchResponse.Facet.values] + are returned. + + Allowed values are: + + - "count desc", which means order by + [SearchResponse.Facet.values.count][google.cloud.retail.v2alpha.SearchResponse.Facet.FacetValue.count] + descending. + + - "value desc", which means order by + [SearchResponse.Facet.values.value][google.cloud.retail.v2alpha.SearchResponse.Facet.FacetValue.value] + descending. Only applies to textual facets. + + If not set, textual values are sorted in `natural + order `__; + numerical intervals are sorted in the order given by + [FacetSpec.FacetKey.intervals][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.intervals]; + [FulfillmentInfo.place_ids][google.cloud.retail.v2alpha.FulfillmentInfo.place_ids] + are sorted in the order given by + [FacetSpec.FacetKey.restricted_values][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.restricted_values]. + query (str): + The query that is used to compute facet for the given facet + key. When provided, it will override the default behavior of + facet computation. The query syntax is the same as a filter + expression. See + [SearchRequest.filter][google.cloud.retail.v2alpha.SearchRequest.filter] + for detail syntax and limitations. Notice that there is no + limitation on + [FacetKey.key][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.key] + when query is specified. + + In the response, + [SearchResponse.Facet.values.value][google.cloud.retail.v2alpha.SearchResponse.Facet.FacetValue.value] + will be always "1" and + [SearchResponse.Facet.values.count][google.cloud.retail.v2alpha.SearchResponse.Facet.FacetValue.count] + will be the number of results that match the query. + + For example, you can set a customized facet for + "shipToStore", where + [FacetKey.key][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.key] + is "customizedShipToStore", and + [FacetKey.query][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.query] + is "availability: ANY("IN_STOCK") AND shipToStore: + ANY("123")". Then the facet will count the products that are + both in stock and ship to store "123". + return_min_max (bool): + Returns the min and max value for each + numerical facet intervals. Ignored for textual + facets. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + intervals: MutableSequence[common.Interval] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.Interval, + ) + restricted_values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + prefixes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + contains: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + case_insensitive: bool = proto.Field( + proto.BOOL, + number=10, + ) + order_by: str = proto.Field( + proto.STRING, + number=4, + ) + query: str = proto.Field( + proto.STRING, + number=5, + ) + return_min_max: bool = proto.Field( + proto.BOOL, + number=11, + ) + + facet_key: 'SearchRequest.FacetSpec.FacetKey' = proto.Field( + proto.MESSAGE, + number=1, + message='SearchRequest.FacetSpec.FacetKey', + ) + limit: int = proto.Field( + proto.INT32, + number=2, + ) + excluded_filter_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + enable_dynamic_position: bool = proto.Field( + proto.BOOL, + number=4, + ) + + class DynamicFacetSpec(proto.Message): + r"""The specifications of dynamically generated facets. + + Attributes: + mode (google.cloud.retail_v2alpha.types.SearchRequest.DynamicFacetSpec.Mode): + Mode of the DynamicFacet feature. Defaults to + [Mode.DISABLED][google.cloud.retail.v2alpha.SearchRequest.DynamicFacetSpec.Mode.DISABLED] + if it's unset. + """ + class Mode(proto.Enum): + r"""Enum to control DynamicFacet mode + + Values: + MODE_UNSPECIFIED (0): + Default value. + DISABLED (1): + Disable Dynamic Facet. + ENABLED (2): + Automatic mode built by Google Retail Search. + """ + MODE_UNSPECIFIED = 0 + DISABLED = 1 + ENABLED = 2 + + mode: 'SearchRequest.DynamicFacetSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.DynamicFacetSpec.Mode', + ) + + class BoostSpec(proto.Message): + r"""Boost specification to boost certain items. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + condition_boost_specs (MutableSequence[google.cloud.retail_v2alpha.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + Condition boost specifications. If a product + matches multiple conditions in the + specifictions, boost scores from these + specifications are all applied and combined in a + non-linear way. Maximum number of specifications + is 20. + skip_boost_spec_validation (bool): + Whether to skip boostspec validation. If this field is set + to true, invalid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2alpha.SearchRequest.BoostSpec.condition_boost_specs] + will be ignored and valid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2alpha.SearchRequest.BoostSpec.condition_boost_specs] + will still be applied. + + This field is a member of `oneof`_ ``_skip_boost_spec_validation``. + """ + + class ConditionBoostSpec(proto.Message): + r"""Boost applies to products which match a condition. + + Attributes: + condition (str): + An expression which specifies a boost condition. The syntax + and supported fields are the same as a filter expression. + See + [SearchRequest.filter][google.cloud.retail.v2alpha.SearchRequest.filter] + for detail syntax and limitations. + + Examples: + + - To boost products with product ID "product_1" or + "product_2", and color "Red" or "Blue": + + - (id: ANY("product_1", "product_2")) AND + (colorFamilies: ANY("Red","Blue")) + boost (float): + Strength of the condition boost, which should be in [-1, 1]. + Negative boost means demotion. Default is 0.0. + + Setting to 1.0 gives the item a big promotion. However, it + does not necessarily mean that the boosted item will be the + top result at all times, nor that other items will be + excluded. Results could still be shown even when none of + them matches the condition. And results that are + significantly more relevant to the search query can still + trump your heavily favored but irrelevant items. + + Setting to -1.0 gives the item a big demotion. However, + results that are deeply relevant might still be shown. The + item will have an upstream battle to get a fairly high + ranking, but it is not blocked out completely. + + Setting to 0.0 means no boost applied. The boosting + condition is ignored. + """ + + condition: str = proto.Field( + proto.STRING, + number=1, + ) + boost: float = proto.Field( + proto.FLOAT, + number=2, + ) + + condition_boost_specs: MutableSequence['SearchRequest.BoostSpec.ConditionBoostSpec'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='SearchRequest.BoostSpec.ConditionBoostSpec', + ) + skip_boost_spec_validation: bool = proto.Field( + proto.BOOL, + number=2, + optional=True, + ) + + class QueryExpansionSpec(proto.Message): + r"""Specification to determine under which conditions query + expansion should occur. + + Attributes: + condition (google.cloud.retail_v2alpha.types.SearchRequest.QueryExpansionSpec.Condition): + The condition under which query expansion should occur. + Default to + [Condition.DISABLED][google.cloud.retail.v2alpha.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. + pin_unexpanded_results (bool): + Whether to pin unexpanded results. If this + field is set to true, unexpanded products are + always at the top of the search results, + followed by the expanded results. + """ + class Condition(proto.Enum): + r"""Enum describing under which condition query expansion should + occur. + + Values: + CONDITION_UNSPECIFIED (0): + Unspecified query expansion condition. In this case, server + behavior defaults to + [Condition.DISABLED][google.cloud.retail.v2alpha.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. + DISABLED (1): + Disabled query expansion. Only the exact search query is + used, even if + [SearchResponse.total_size][google.cloud.retail.v2alpha.SearchResponse.total_size] + is zero. + AUTO (3): + Automatic query expansion built by Google + Retail Search. + """ + CONDITION_UNSPECIFIED = 0 + DISABLED = 1 + AUTO = 3 + + condition: 'SearchRequest.QueryExpansionSpec.Condition' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.QueryExpansionSpec.Condition', + ) + pin_unexpanded_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class PersonalizationSpec(proto.Message): + r"""The specification for personalization. + + Attributes: + mode (google.cloud.retail_v2alpha.types.SearchRequest.PersonalizationSpec.Mode): + Defaults to + [Mode.AUTO][google.cloud.retail.v2alpha.SearchRequest.PersonalizationSpec.Mode.AUTO]. + """ + class Mode(proto.Enum): + r"""The personalization mode of each search request. + + Values: + MODE_UNSPECIFIED (0): + Default value. In this case, server behavior defaults to + [Mode.AUTO][google.cloud.retail.v2alpha.SearchRequest.PersonalizationSpec.Mode.AUTO]. + AUTO (1): + Let CRS decide whether to use personalization + based on quality of user event data. + DISABLED (2): + Disable personalization. + """ + MODE_UNSPECIFIED = 0 + AUTO = 1 + DISABLED = 2 + + mode: 'SearchRequest.PersonalizationSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.PersonalizationSpec.Mode', + ) + + class SpellCorrectionSpec(proto.Message): + r"""The specification for query spell correction. + + Attributes: + mode (google.cloud.retail_v2alpha.types.SearchRequest.SpellCorrectionSpec.Mode): + The mode under which spell correction should take effect to + replace the original search query. Default to + [Mode.AUTO][google.cloud.retail.v2alpha.SearchRequest.SpellCorrectionSpec.Mode.AUTO]. + """ + class Mode(proto.Enum): + r"""Enum describing under which mode spell correction should + occur. + + Values: + MODE_UNSPECIFIED (0): + Unspecified spell correction mode. In this case, server + behavior defaults to + [Mode.AUTO][google.cloud.retail.v2alpha.SearchRequest.SpellCorrectionSpec.Mode.AUTO]. + SUGGESTION_ONLY (1): + Google Retail Search will try to find a spell suggestion if + there is any and put in the + [SearchResponse.corrected_query][google.cloud.retail.v2alpha.SearchResponse.corrected_query]. + The spell suggestion will not be used as the search query. + AUTO (2): + Automatic spell correction built by Google + Retail Search. Search will be based on the + corrected query if found. + """ + MODE_UNSPECIFIED = 0 + SUGGESTION_ONLY = 1 + AUTO = 2 + + mode: 'SearchRequest.SpellCorrectionSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.SpellCorrectionSpec.Mode', + ) + + placement: str = proto.Field( + proto.STRING, + number=1, + ) + branch: str = proto.Field( + proto.STRING, + number=2, + ) + query: str = proto.Field( + proto.STRING, + number=3, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=4, + ) + user_info: common.UserInfo = proto.Field( + proto.MESSAGE, + number=5, + message=common.UserInfo, + ) + page_size: int = proto.Field( + proto.INT32, + number=7, + ) + page_token: str = proto.Field( + proto.STRING, + number=8, + ) + offset: int = proto.Field( + proto.INT32, + number=9, + ) + filter: str = proto.Field( + proto.STRING, + number=10, + ) + canonical_filter: str = proto.Field( + proto.STRING, + number=28, + ) + order_by: str = proto.Field( + proto.STRING, + number=11, + ) + facet_specs: MutableSequence[FacetSpec] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message=FacetSpec, + ) + dynamic_facet_spec: DynamicFacetSpec = proto.Field( + proto.MESSAGE, + number=21, + message=DynamicFacetSpec, + ) + boost_spec: BoostSpec = proto.Field( + proto.MESSAGE, + number=13, + message=BoostSpec, + ) + query_expansion_spec: QueryExpansionSpec = proto.Field( + proto.MESSAGE, + number=14, + message=QueryExpansionSpec, + ) + relevance_threshold: RelevanceThreshold = proto.Field( + proto.ENUM, + number=15, + enum=RelevanceThreshold, + ) + variant_rollup_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=17, + ) + page_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=23, + ) + search_mode: SearchMode = proto.Field( + proto.ENUM, + number=31, + enum=SearchMode, + ) + personalization_spec: PersonalizationSpec = proto.Field( + proto.MESSAGE, + number=32, + message=PersonalizationSpec, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=34, + ) + spell_correction_spec: SpellCorrectionSpec = proto.Field( + proto.MESSAGE, + number=35, + optional=True, + message=SpellCorrectionSpec, + ) + entity: str = proto.Field( + proto.STRING, + number=38, + ) + + +class SearchResponse(proto.Message): + r"""Response message for + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search] + method. + + Attributes: + results (MutableSequence[google.cloud.retail_v2alpha.types.SearchResponse.SearchResult]): + A list of matched items. The order represents + the ranking. + facets (MutableSequence[google.cloud.retail_v2alpha.types.SearchResponse.Facet]): + Results of facets requested by user. + total_size (int): + The estimated total count of matched items irrespective of + pagination. The count of + [results][google.cloud.retail.v2alpha.SearchResponse.results] + returned by pagination may be less than the + [total_size][google.cloud.retail.v2alpha.SearchResponse.total_size] + that matches. + corrected_query (str): + Contains the spell corrected query, if found. If the spell + correction type is AUTOMATIC, then the search results are + based on corrected_query. Otherwise the original query is + used for search. + attribution_token (str): + A unique search token. This should be included in the + [UserEvent][google.cloud.retail.v2alpha.UserEvent] logs + resulting from this search, which enables accurate + attribution of search model performance. + next_page_token (str): + A token that can be sent as + [SearchRequest.page_token][google.cloud.retail.v2alpha.SearchRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + query_expansion_info (google.cloud.retail_v2alpha.types.SearchResponse.QueryExpansionInfo): + Query expansion information for the returned + results. + redirect_uri (str): + The URI of a customer-defined redirect page. If redirect + action is triggered, no search is performed, and only + [redirect_uri][google.cloud.retail.v2alpha.SearchResponse.redirect_uri] + and + [attribution_token][google.cloud.retail.v2alpha.SearchResponse.attribution_token] + are set in the response. + applied_controls (MutableSequence[str]): + The fully qualified resource name of applied + `controls `__. + invalid_condition_boost_specs (MutableSequence[google.cloud.retail_v2alpha.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + The invalid + [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2alpha.SearchRequest.BoostSpec.condition_boost_specs] + that are not applied during serving. + experiment_info (MutableSequence[google.cloud.retail_v2alpha.types.ExperimentInfo]): + Metadata related to A/B testing + [Experiment][google.cloud.retail.v2alpha.Experiment] + associated with this response. Only exists when an + experiment is triggered. + """ + + class SearchResult(proto.Message): + r"""Represents the search results. + + Attributes: + id (str): + [Product.id][google.cloud.retail.v2alpha.Product.id] of the + searched [Product][google.cloud.retail.v2alpha.Product]. + product (google.cloud.retail_v2alpha.types.Product): + The product data snippet in the search response. Only + [Product.name][google.cloud.retail.v2alpha.Product.name] is + guaranteed to be populated. + + [Product.variants][google.cloud.retail.v2alpha.Product.variants] + contains the product variants that match the search query. + If there are multiple product variants matching the query, + top 5 most relevant product variants are returned and + ordered by relevancy. + + If relevancy can be deternmined, use + [matching_variant_fields][google.cloud.retail.v2alpha.SearchResponse.SearchResult.matching_variant_fields] + to look up matched product variants fields. If relevancy + cannot be determined, e.g. when searching "shoe" all + products in a shoe product can be a match, 5 product + variants are returned but order is meaningless. + matching_variant_count (int): + The count of matched + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product]s. + matching_variant_fields (MutableMapping[str, google.protobuf.field_mask_pb2.FieldMask]): + If a + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product] matches the + search query, this map indicates which + [Product][google.cloud.retail.v2alpha.Product] fields are + matched. The key is the + [Product.name][google.cloud.retail.v2alpha.Product.name], + the value is a field mask of the matched + [Product][google.cloud.retail.v2alpha.Product] fields. If + matched attributes cannot be determined, this map will be + empty. + + For example, a key "sku1" with field mask + "products.color_info" indicates there is a match between + "sku1" [ColorInfo][google.cloud.retail.v2alpha.ColorInfo] + and the query. + variant_rollup_values (MutableMapping[str, google.protobuf.struct_pb2.Value]): + The rollup matching + [variant][google.cloud.retail.v2alpha.Product.Type.VARIANT] + [Product][google.cloud.retail.v2alpha.Product] attributes. + The key is one of the + [SearchRequest.variant_rollup_keys][google.cloud.retail.v2alpha.SearchRequest.variant_rollup_keys]. + The values are the merged and de-duplicated + [Product][google.cloud.retail.v2alpha.Product] attributes. + Notice that the rollup values are respect filter. For + example, when filtering by "colorFamilies:ANY("red")" and + rollup "colorFamilies", only "red" is returned. + + For textual and numerical attributes, the rollup values is a + list of string or double values with type + [google.protobuf.ListValue][google.protobuf.ListValue]. For + example, if there are two variants with colors "red" and + "blue", the rollup values are + + :: + + { key: "colorFamilies" + value { + list_value { + values { string_value: "red" } + values { string_value: "blue" } + } + } + } + + For + [FulfillmentInfo][google.cloud.retail.v2alpha.FulfillmentInfo], + the rollup values is a double value with type + [google.protobuf.Value][google.protobuf.Value]. For example, + ``{key: "pickupInStore.store1" value { number_value: 10 }}`` + means a there are 10 variants in this product are available + in the store "store1". + personal_labels (MutableSequence[str]): + Specifies previous events related to this product for this + user based on + [UserEvent][google.cloud.retail.v2alpha.UserEvent] with same + [SearchRequest.visitor_id][google.cloud.retail.v2alpha.SearchRequest.visitor_id] + or + [UserInfo.user_id][google.cloud.retail.v2alpha.UserInfo.user_id]. + + This is set only when + [SearchRequest.PersonalizationSpec.mode][google.cloud.retail.v2alpha.SearchRequest.PersonalizationSpec.mode] + is + [SearchRequest.PersonalizationSpec.Mode.AUTO][google.cloud.retail.v2alpha.SearchRequest.PersonalizationSpec.Mode.AUTO]. + + Possible values: + + - ``purchased``: Indicates that this product has been + purchased before. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + matching_variant_count: int = proto.Field( + proto.INT32, + number=3, + ) + matching_variant_fields: MutableMapping[str, field_mask_pb2.FieldMask] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + variant_rollup_values: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=5, + message=struct_pb2.Value, + ) + personal_labels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + + class Facet(proto.Message): + r"""A facet result. + + Attributes: + key (str): + The key for this facet. E.g., "colorFamilies" + or "price" or "attributes.attr1". + values (MutableSequence[google.cloud.retail_v2alpha.types.SearchResponse.Facet.FacetValue]): + The facet values for this field. + dynamic_facet (bool): + Whether the facet is dynamically generated. + """ + + class FacetValue(proto.Message): + r"""A facet value which contains value names and their count. + + 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: + value (str): + Text value of a facet, such as "Black" for + facet "colorFamilies". + + This field is a member of `oneof`_ ``facet_value``. + interval (google.cloud.retail_v2alpha.types.Interval): + Interval value for a facet, such as [10, 20) for facet + "price". + + This field is a member of `oneof`_ ``facet_value``. + count (int): + Number of items that have this facet value. + min_value (float): + The minimum value in the + [FacetValue.interval][google.cloud.retail.v2alpha.SearchResponse.Facet.FacetValue.interval]. + Only supported on numerical facets and returned if + [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.return_min_max] + is true. + max_value (float): + The maximum value in the + [FacetValue.interval][google.cloud.retail.v2alpha.SearchResponse.Facet.FacetValue.interval]. + Only supported on numerical facets and returned if + [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2alpha.SearchRequest.FacetSpec.FacetKey.return_min_max] + is true. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + oneof='facet_value', + ) + interval: common.Interval = proto.Field( + proto.MESSAGE, + number=2, + oneof='facet_value', + message=common.Interval, + ) + count: int = proto.Field( + proto.INT64, + number=3, + ) + min_value: float = proto.Field( + proto.DOUBLE, + number=5, + ) + max_value: float = proto.Field( + proto.DOUBLE, + number=6, + ) + + key: str = proto.Field( + proto.STRING, + number=1, + ) + values: MutableSequence['SearchResponse.Facet.FacetValue'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='SearchResponse.Facet.FacetValue', + ) + dynamic_facet: bool = proto.Field( + proto.BOOL, + number=3, + ) + + class QueryExpansionInfo(proto.Message): + r"""Information describing query expansion including whether + expansion has occurred. + + Attributes: + expanded_query (bool): + Bool describing whether query expansion has + occurred. + pinned_result_count (int): + Number of pinned results. This field will only be set when + expansion happens and + [SearchRequest.QueryExpansionSpec.pin_unexpanded_results][google.cloud.retail.v2alpha.SearchRequest.QueryExpansionSpec.pin_unexpanded_results] + is set to true. + """ + + expanded_query: bool = proto.Field( + proto.BOOL, + number=1, + ) + pinned_result_count: int = proto.Field( + proto.INT64, + number=2, + ) + + @property + def raw_page(self): + return self + + results: MutableSequence[SearchResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=SearchResult, + ) + facets: MutableSequence[Facet] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Facet, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + corrected_query: str = proto.Field( + proto.STRING, + number=4, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=5, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=6, + ) + query_expansion_info: QueryExpansionInfo = proto.Field( + proto.MESSAGE, + number=7, + message=QueryExpansionInfo, + ) + redirect_uri: str = proto.Field( + proto.STRING, + number=10, + ) + applied_controls: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + invalid_condition_boost_specs: MutableSequence['SearchRequest.BoostSpec.ConditionBoostSpec'] = proto.RepeatedField( + proto.MESSAGE, + number=14, + message='SearchRequest.BoostSpec.ConditionBoostSpec', + ) + experiment_info: MutableSequence['ExperimentInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=17, + message='ExperimentInfo', + ) + + +class ExperimentInfo(proto.Message): + r"""Metadata for active A/B testing [Experiments][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + serving_config_experiment (google.cloud.retail_v2alpha.types.ExperimentInfo.ServingConfigExperiment): + A/B test between existing Cloud Retail Search + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig]s. + + This field is a member of `oneof`_ ``experiment_metadata``. + experiment (str): + The fully qualified resource name of the experiment that + provides the serving config under test, should an active + experiment exist. For example: + ``projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`` + """ + + class ServingConfigExperiment(proto.Message): + r"""Metadata for active serving config A/B tests. + + Attributes: + original_serving_config (str): + The fully qualified resource name of the original + [SearchRequest.placement][google.cloud.retail.v2alpha.SearchRequest.placement] + in the search request prior to reassignment by experiment + API. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + experiment_serving_config (str): + The fully qualified resource name of the serving config + [VariantArm.serving_config_id][] responsible for generating + the search response. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + """ + + original_serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + experiment_serving_config: str = proto.Field( + proto.STRING, + number=2, + ) + + serving_config_experiment: ServingConfigExperiment = proto.Field( + proto.MESSAGE, + number=2, + oneof='experiment_metadata', + message=ServingConfigExperiment, + ) + experiment: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config.py new file mode 100644 index 00000000..7591ef45 --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config.py @@ -0,0 +1,359 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import search_service + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'ServingConfig', + }, +) + + +class ServingConfig(proto.Message): + r"""Configures metadata that is used to generate serving time + results (e.g. search results or recommendation predictions). + + Attributes: + name (str): + Immutable. Fully qualified name + ``projects/*/locations/global/catalogs/*/servingConfig/*`` + display_name (str): + Required. The human readable serving config display name. + Used in Retail UI. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + model_id (str): + The id of the model in the same + [Catalog][google.cloud.retail.v2alpha.Catalog] to use at + serving time. Currently only RecommendationModels are + supported: + https://cloud.google.com/retail/recommendations-ai/docs/create-models + Can be changed but only to a compatible model (e.g. + others-you-may-like CTR to others-you-may-like CVR). + + Required when + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + price_reranking_level (str): + How much price ranking we want in serving results. Price + reranking causes product items with a similar recommendation + probability to be ordered by price, with the highest-priced + items first. This setting could result in a decrease in + click-through and conversion rates. Allowed values are: + + - ``no-price-reranking`` + - ``low-price-reranking`` + - ``medium-price-reranking`` + - ``high-price-reranking`` + + If not specified, we choose default based on model type. + Default value: ``no-price-reranking``. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + facet_control_ids (MutableSequence[str]): + Facet specifications for faceted search. If empty, no facets + are returned. The ids refer to the ids of + [Control][google.cloud.retail.v2alpha.Control] resources + with only the Facet control set. These controls are assumed + to be in the same + [Catalog][google.cloud.retail.v2alpha.Catalog] as the + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig]. + A maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + dynamic_facet_spec (google.cloud.retail_v2alpha.types.SearchRequest.DynamicFacetSpec): + The specification for dynamically generated facets. Notice + that only textual facets can be dynamically generated. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + boost_control_ids (MutableSequence[str]): + Condition boost specifications. If a product matches + multiple conditions in the specifications, boost scores from + these specifications are all applied and combined in a + non-linear way. Maximum number of specifications is 100. + + Notice that if both + [ServingConfig.boost_control_ids][google.cloud.retail.v2alpha.ServingConfig.boost_control_ids] + and + [SearchRequest.boost_spec][google.cloud.retail.v2alpha.SearchRequest.boost_spec] + are set, the boost conditions from both places are + evaluated. If a search request matches multiple boost + conditions, the final boost score is equal to the sum of the + boost scores from all matched boost conditions. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + filter_control_ids (MutableSequence[str]): + Condition filter specifications. If a product matches + multiple conditions in the specifications, filters from + these specifications are all applied and combined via the + AND operator. Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + redirect_control_ids (MutableSequence[str]): + Condition redirect specifications. Only the first triggered + redirect action is applied, even if multiple apply. Maximum + number of specifications is 1000. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + twoway_synonyms_control_ids (MutableSequence[str]): + Condition synonyms specifications. If multiple syonyms + conditions match, all matching synonyms control in the list + will execute. Order of controls in the list will not matter. + Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + oneway_synonyms_control_ids (MutableSequence[str]): + Condition oneway synonyms specifications. If multiple oneway + synonyms conditions match, all matching oneway synonyms + controls in the list will execute. Order of controls in the + list will not matter. Maximum number of specifications is + 100. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + do_not_associate_control_ids (MutableSequence[str]): + Condition do not associate specifications. If multiple do + not associate conditions match, all matching do not + associate controls in the list will execute. + + - Order does not matter. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + replacement_control_ids (MutableSequence[str]): + Condition replacement specifications. + + - Applied according to the order in the list. + - A previously replaced term can not be re-replaced. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + ignore_control_ids (MutableSequence[str]): + Condition ignore specifications. If multiple ignore + conditions match, all matching ignore controls in the list + will execute. + + - Order does not matter. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + diversity_level (str): + How much diversity to use in recommendation model results + e.g. ``medium-diversity`` or ``high-diversity``. Currently + supported values: + + - ``no-diversity`` + - ``low-diversity`` + - ``medium-diversity`` + - ``high-diversity`` + - ``auto-diversity`` + + If not specified, we choose default based on recommendation + model type. Default value: ``no-diversity``. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + diversity_type (google.cloud.retail_v2alpha.types.ServingConfig.DiversityType): + What kind of diversity to use - data driven or rule based. + If unset, the server behavior defaults to + [RULE_BASED_DIVERSITY][google.cloud.retail.v2alpha.ServingConfig.DiversityType.RULE_BASED_DIVERSITY]. + enable_category_filter_level (str): + Whether to add additional category filters on the + ``similar-items`` model. If not specified, we enable it by + default. Allowed values are: + + - ``no-category-match``: No additional filtering of + original results from the model and the customer's + filters. + - ``relaxed-category-match``: Only keep results with + categories that match at least one item categories in the + PredictRequests's context item. + + - If customer also sends filters in the PredictRequest, + then the results will satisfy both conditions (user + given and category match). + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + personalization_spec (google.cloud.retail_v2alpha.types.SearchRequest.PersonalizationSpec): + The specification for personalization spec. + + Can only be set if + [solution_types][google.cloud.retail.v2alpha.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2alpha.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2alpha.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2alpha.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2alpha.ServingConfig.personalization_spec]. + solution_types (MutableSequence[google.cloud.retail_v2alpha.types.SolutionType]): + Required. Immutable. Specifies the solution + types that a serving config can be associated + with. Currently we support setting only one type + of solution. + """ + class DiversityType(proto.Enum): + r"""What type of diversity - data or rule based. + + Values: + DIVERSITY_TYPE_UNSPECIFIED (0): + Default value. + RULE_BASED_DIVERSITY (2): + Rule based diversity. + DATA_DRIVEN_DIVERSITY (3): + Data driven diversity. + """ + DIVERSITY_TYPE_UNSPECIFIED = 0 + RULE_BASED_DIVERSITY = 2 + DATA_DRIVEN_DIVERSITY = 3 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + model_id: str = proto.Field( + proto.STRING, + number=3, + ) + price_reranking_level: str = proto.Field( + proto.STRING, + number=4, + ) + facet_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + dynamic_facet_spec: search_service.SearchRequest.DynamicFacetSpec = proto.Field( + proto.MESSAGE, + number=6, + message=search_service.SearchRequest.DynamicFacetSpec, + ) + boost_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + filter_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + redirect_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=10, + ) + twoway_synonyms_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=18, + ) + oneway_synonyms_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + do_not_associate_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + replacement_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=14, + ) + ignore_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=15, + ) + diversity_level: str = proto.Field( + proto.STRING, + number=8, + ) + diversity_type: DiversityType = proto.Field( + proto.ENUM, + number=20, + enum=DiversityType, + ) + enable_category_filter_level: str = proto.Field( + proto.STRING, + number=16, + ) + personalization_spec: search_service.SearchRequest.PersonalizationSpec = proto.Field( + proto.MESSAGE, + number=21, + message=search_service.SearchRequest.PersonalizationSpec, + ) + solution_types: MutableSequence[common.SolutionType] = proto.RepeatedField( + proto.ENUM, + number=19, + enum=common.SolutionType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config_service.py new file mode 100644 index 00000000..cbb4135a --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/serving_config_service.py @@ -0,0 +1,238 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import serving_config as gcr_serving_config +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'CreateServingConfigRequest', + 'UpdateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'AddControlRequest', + 'RemoveControlRequest', + }, +) + + +class CreateServingConfigRequest(proto.Message): + r"""Request for CreateServingConfig method. + + Attributes: + parent (str): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + serving_config (google.cloud.retail_v2alpha.types.ServingConfig): + Required. The ServingConfig to create. + serving_config_id (str): + Required. The ID to use for the ServingConfig, which will + become the final component of the ServingConfig's resource + name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-_/. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + serving_config: gcr_serving_config.ServingConfig = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_serving_config.ServingConfig, + ) + serving_config_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class UpdateServingConfigRequest(proto.Message): + r"""Request for UpdateServingConfig method. + + Attributes: + serving_config (google.cloud.retail_v2alpha.types.ServingConfig): + Required. The ServingConfig to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2alpha.ServingConfig] + to update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2alpha.ServingConfig.name] + + If not set, all supported fields are updated. + """ + + serving_config: gcr_serving_config.ServingConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_serving_config.ServingConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteServingConfigRequest(proto.Message): + r"""Request for DeleteServingConfig method. + + Attributes: + name (str): + Required. The resource name of the ServingConfig to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetServingConfigRequest(proto.Message): + r"""Request for GetServingConfig method. + + Attributes: + name (str): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListServingConfigsRequest(proto.Message): + r"""Request for ListServingConfigs method. + + Attributes: + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 100. If a + value greater than 100 is provided, at most 100 + results are returned. + page_token (str): + Optional. A page token, received from a previous + ``ListServingConfigs`` call. Provide this to retrieve the + subsequent page. + """ + + 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 ListServingConfigsResponse(proto.Message): + r"""Response for ListServingConfigs method. + + Attributes: + serving_configs (MutableSequence[google.cloud.retail_v2alpha.types.ServingConfig]): + All the ServingConfigs for a given catalog. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + serving_configs: MutableSequence[gcr_serving_config.ServingConfig] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_serving_config.ServingConfig, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class AddControlRequest(proto.Message): + r"""Request for AddControl method. + + Attributes: + serving_config (str): + Required. The source ServingConfig resource name . Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + control_id (str): + Required. The id of the control to apply. Assumed to be in + the same catalog as the serving config - if id is not found + a NOT_FOUND error is returned. + """ + + serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + control_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RemoveControlRequest(proto.Message): + r"""Request for RemoveControl method. + + Attributes: + serving_config (str): + Required. The source ServingConfig resource name . Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + control_id (str): + Required. The id of the control to apply. + Assumed to be in the same catalog as the serving + config. + """ + + serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + control_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event.py new file mode 100644 index 00000000..441bf0fb --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'UserEvent', + 'ProductDetail', + 'CompletionDetail', + 'PurchaseTransaction', + }, +) + + +class UserEvent(proto.Message): + r"""UserEvent captures all metadata information Retail API needs + to know about how end users interact with customers' website. + + Attributes: + event_type (str): + Required. User event type. Allowed values are: + + - ``add-to-cart``: Products being added to cart. + - ``category-page-view``: Special pages such as sale or + promotion pages viewed. + - ``detail-page-view``: Products detail page viewed. + - ``home-page-view``: Homepage viewed. + - ``promotion-offered``: Promotion is offered to a user. + - ``promotion-not-offered``: Promotion is not offered to a + user. + - ``purchase-complete``: User finishing a purchase. + - ``search``: Product search. + - ``shopping-cart-page-view``: User viewing a shopping + cart. + visitor_id (str): + Required. A unique identifier for tracking visitors. + + For example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor log in/out of the website. + + Don't set the field to the same fixed ID for different + users. This mixes the event history of those users together, + which results in degraded model quality. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + The field should not contain PII or user-data. We recommend + to use Google Analytics `Client + ID `__ + for this field. + session_id (str): + A unique identifier for tracking a visitor session with a + length limit of 128 bytes. A session is an aggregation of an + end user behavior in a time span. + + A general guideline to populate the sesion_id: + + 1. If user has no activity for 30 min, a new session_id + should be assigned. + 2. The session_id should be unique across users, suggest use + uuid or add visitor_id as prefix. + event_time (google.protobuf.timestamp_pb2.Timestamp): + Only required for + [UserEventService.ImportUserEvents][google.cloud.retail.v2alpha.UserEventService.ImportUserEvents] + method. Timestamp of when the user event happened. + experiment_ids (MutableSequence[str]): + A list of identifiers for the independent + experiment groups this user event belongs to. + This is used to distinguish between user events + associated with different experiment setups + (e.g. using Retail API, using different + recommendation models). + attribution_token (str): + Highly recommended for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2alpha.PredictionService.Predict]. + This field enables accurate attribution of recommendation + model performance. + + The value must be a valid + [PredictResponse.attribution_token][google.cloud.retail.v2alpha.PredictResponse.attribution_token] + for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2alpha.PredictionService.Predict]. + The value must be a valid + [SearchResponse.attribution_token][google.cloud.retail.v2alpha.SearchResponse.attribution_token] + for user events that are the result of + [SearchService.Search][google.cloud.retail.v2alpha.SearchService.Search]. + + This token enables us to accurately attribute page view or + purchase back to the event and the particular predict + response containing this clicked/purchased product. If user + clicks on product K in the recommendation results, pass + [PredictResponse.attribution_token][google.cloud.retail.v2alpha.PredictResponse.attribution_token] + as a URL parameter to product K's page. When recording + events on product K's page, log the + [PredictResponse.attribution_token][google.cloud.retail.v2alpha.PredictResponse.attribution_token] + to this field. + product_details (MutableSequence[google.cloud.retail_v2alpha.types.ProductDetail]): + The main product details related to the event. + + This field is optional except for the following event types: + + - ``add-to-cart`` + - ``detail-page-view`` + - ``purchase-complete`` + + In a ``search`` event, this field represents the products + returned to the end user on the current page (the end user + may have not finished browsing the whole page yet). When a + new page is returned to the end user, after + pagination/filtering/ordering even for the same query, a new + ``search`` event with different + [product_details][google.cloud.retail.v2alpha.UserEvent.product_details] + is desired. The end user may have not finished browsing the + whole page yet. + completion_detail (google.cloud.retail_v2alpha.types.CompletionDetail): + The main auto-completion details related to the event. + + This field should be set for ``search`` event when + autocomplete function is enabled and the user clicks a + suggestion for search. + attributes (MutableMapping[str, google.cloud.retail_v2alpha.types.CustomAttribute]): + Extra user event features to include in the recommendation + model. + + If you provide custom attributes for ingested user events, + also include them in the user events that you associate with + prediction requests. Custom attribute formatting must be + consistent between imported events and events provided with + prediction requests. This lets the Retail API use those + custom attributes when training models and serving + predictions, which helps improve recommendation quality. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - The key must be a UTF-8 encoded string with a length + limit of 5,000 characters. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a UTF-8 + encoded string with a length limit of 256 characters. + - For number attributes, at most 400 values are allowed. + + For product recommendations, an example of extra user + information is traffic_channel, which is how a user arrives + at the site. Users can arrive at the site by coming to the + site directly, coming through Google search, or in other + ways. + cart_id (str): + The ID or name of the associated shopping cart. This ID is + used to associate multiple items added or present in the + cart before purchase. + + This can only be set for ``add-to-cart``, + ``purchase-complete``, or ``shopping-cart-page-view`` + events. + purchase_transaction (google.cloud.retail_v2alpha.types.PurchaseTransaction): + A transaction represents the entire purchase transaction. + + Required for ``purchase-complete`` events. Other event types + should not set this field. Otherwise, an INVALID_ARGUMENT + error is returned. + search_query (str): + The user's search query. + + See + [SearchRequest.query][google.cloud.retail.v2alpha.SearchRequest.query] + for definition. + + The value must be a UTF-8 encoded string with a length limit + of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + At least one of + [search_query][google.cloud.retail.v2alpha.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2alpha.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. + + See + [SearchRequest.filter][google.cloud.retail.v2alpha.SearchRequest.filter] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + order_by (str): + The order in which products are returned. + + See + [SearchRequest.order_by][google.cloud.retail.v2alpha.SearchRequest.order_by] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + offset (int): + An integer that specifies the current offset for pagination + (the 0-indexed starting location, amongst the products + deemed by the API as relevant). + + See + [SearchRequest.offset][google.cloud.retail.v2alpha.SearchRequest.offset] + for definition. + + If this field is negative, an INVALID_ARGUMENT is returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + page_categories (MutableSequence[str]): + The categories associated with a category page. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + + Required for ``category-page-view`` events. At least one of + [search_query][google.cloud.retail.v2alpha.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2alpha.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + user_info (google.cloud.retail_v2alpha.types.UserInfo): + User information. + uri (str): + Complete URL (window.location.href) of the + user's current page. + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. Maximum length + 5,000 characters. + referrer_uri (str): + The referrer URL of the current page. + + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. + page_view_id (str): + A unique ID of a web page view. + + This should be kept the same for all user events triggered + from the same pageview. For example, an item detail page + view could trigger multiple events as the user is browsing + the page. The ``pageViewId`` property should be kept the + same for all these events so that they can be grouped + together properly. + + When using the client side event reporting with JavaScript + pixel and Google Tag Manager, this value is filled in + automatically. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. It is recommended to set this field to + get better per-entity search, completion and prediction + results. + """ + + event_type: str = proto.Field( + proto.STRING, + number=1, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=2, + ) + session_id: str = proto.Field( + proto.STRING, + number=21, + ) + event_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + experiment_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=5, + ) + product_details: MutableSequence['ProductDetail'] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message='ProductDetail', + ) + completion_detail: 'CompletionDetail' = proto.Field( + proto.MESSAGE, + number=22, + message='CompletionDetail', + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=common.CustomAttribute, + ) + cart_id: str = proto.Field( + proto.STRING, + number=8, + ) + purchase_transaction: 'PurchaseTransaction' = proto.Field( + proto.MESSAGE, + number=9, + message='PurchaseTransaction', + ) + search_query: str = proto.Field( + proto.STRING, + number=10, + ) + filter: str = proto.Field( + proto.STRING, + number=16, + ) + order_by: str = proto.Field( + proto.STRING, + number=17, + ) + offset: int = proto.Field( + proto.INT32, + number=18, + ) + page_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + user_info: common.UserInfo = proto.Field( + proto.MESSAGE, + number=12, + message=common.UserInfo, + ) + uri: str = proto.Field( + proto.STRING, + number=13, + ) + referrer_uri: str = proto.Field( + proto.STRING, + number=14, + ) + page_view_id: str = proto.Field( + proto.STRING, + number=15, + ) + entity: str = proto.Field( + proto.STRING, + number=23, + ) + + +class ProductDetail(proto.Message): + r"""Detailed product information associated with a user event. + + Attributes: + product (google.cloud.retail_v2alpha.types.Product): + Required. [Product][google.cloud.retail.v2alpha.Product] + information. + + Required field(s): + + - [Product.id][google.cloud.retail.v2alpha.Product.id] + + Optional override field(s): + + - [Product.price_info][google.cloud.retail.v2alpha.Product.price_info] + + If any supported optional fields are provided, we will treat + them as a full override when looking up product information + from the catalog. Thus, it is important to ensure that the + overriding fields are accurate and complete. + + All other product fields are ignored and instead populated + via catalog lookup after event ingestion. + quantity (google.protobuf.wrappers_pb2.Int32Value): + Quantity of the product associated with the user event. + + For example, this field will be 2 if two products are added + to the shopping cart for ``purchase-complete`` event. + Required for ``add-to-cart`` and ``purchase-complete`` event + types. + """ + + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + quantity: wrappers_pb2.Int32Value = proto.Field( + proto.MESSAGE, + number=2, + message=wrappers_pb2.Int32Value, + ) + + +class CompletionDetail(proto.Message): + r"""Detailed completion information including completion + attribution token and clicked completion info. + + Attributes: + completion_attribution_token (str): + Completion attribution token in + [CompleteQueryResponse.attribution_token][google.cloud.retail.v2alpha.CompleteQueryResponse.attribution_token]. + selected_suggestion (str): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2alpha.CompleteQueryResponse.CompletionResult.suggestion]. + selected_position (int): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2alpha.CompleteQueryResponse.CompletionResult.suggestion] + position, starting from 0. + """ + + completion_attribution_token: str = proto.Field( + proto.STRING, + number=1, + ) + selected_suggestion: str = proto.Field( + proto.STRING, + number=2, + ) + selected_position: int = proto.Field( + proto.INT32, + number=3, + ) + + +class PurchaseTransaction(proto.Message): + r"""A transaction represents the entire purchase transaction. + + Attributes: + id (str): + The transaction ID with a length limit of 128 + characters. + revenue (float): + Required. Total non-zero revenue or grand + total associated with the transaction. This + value include shipping, tax, or other + adjustments to total revenue that you want to + include as part of your revenue calculations. + tax (float): + All the taxes associated with the + transaction. + cost (float): + All the costs associated with the products. These can be + manufacturing costs, shipping expenses not borne by the end + user, or any other costs, such that: + + - Profit = + [revenue][google.cloud.retail.v2alpha.PurchaseTransaction.revenue] + - + [tax][google.cloud.retail.v2alpha.PurchaseTransaction.tax] + - + [cost][google.cloud.retail.v2alpha.PurchaseTransaction.cost] + currency_code (str): + Required. Currency code. Use three-character + ISO-4217 code. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + revenue: float = proto.Field( + proto.FLOAT, + number=2, + ) + tax: float = proto.Field( + proto.FLOAT, + number=3, + ) + cost: float = proto.Field( + proto.FLOAT, + number=4, + ) + currency_code: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event_service.py b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event_service.py new file mode 100644 index 00000000..7911e7aa --- /dev/null +++ b/owl-bot-staging/v2alpha/google/cloud/retail_v2alpha/types/user_event_service.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 + +from google.cloud.retail_v2alpha.types import user_event as gcr_user_event + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2alpha', + manifest={ + 'WriteUserEventRequest', + 'CollectUserEventRequest', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'RejoinUserEventsMetadata', + }, +) + + +class WriteUserEventRequest(proto.Message): + r"""Request message for WriteUserEvent method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (google.cloud.retail_v2alpha.types.UserEvent): + Required. User event to write. + write_async (bool): + If set to true, the user event will be + written asynchronously after validation, and the + API will respond without waiting for the write. + Therefore, silent failures can occur even if the + API returns success. In case of silent failures, + error messages can be found in Stackdriver logs. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: gcr_user_event.UserEvent = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) + write_async: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class CollectUserEventRequest(proto.Message): + r"""Request message for CollectUserEvent method. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + prebuilt_rule (str): + The prebuilt rule name that can convert a specific type of + raw_json. For example: "ga4_bq" rule for the GA4 user event + schema. + + This field is a member of `oneof`_ ``conversion_rule``. + parent (str): + Required. The parent catalog name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (str): + Required. URL encoded UserEvent proto with a + length limit of 2,000,000 characters. + uri (str): + The URL including cgi-parameters but + excluding the hash fragment with a length limit + of 5,000 characters. This is often more useful + than the referer URL, because many browsers only + send the domain for 3rd party requests. + ets (int): + The event timestamp in milliseconds. This + prevents browser caching of otherwise identical + get requests. The name is abbreviated to reduce + the payload bytes. + raw_json (str): + An arbitrary serialized JSON string that contains necessary + information that can comprise a user event. When this field + is specified, the user_event field will be ignored. Note: + line-delimited JSON is not supported, a single JSON only. + """ + + prebuilt_rule: str = proto.Field( + proto.STRING, + number=6, + oneof='conversion_rule', + ) + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: str = proto.Field( + proto.STRING, + number=2, + ) + uri: str = proto.Field( + proto.STRING, + number=3, + ) + ets: int = proto.Field( + proto.INT64, + number=4, + ) + raw_json: str = proto.Field( + proto.STRING, + number=5, + ) + + +class RejoinUserEventsRequest(proto.Message): + r"""Request message for RejoinUserEvents method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event_rejoin_scope (google.cloud.retail_v2alpha.types.RejoinUserEventsRequest.UserEventRejoinScope): + The type of the user event rejoin to define the scope and + range of the user events to be rejoined with the latest + product catalog. Defaults to + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED`` if this field is not + set, or set to an invalid integer value. + """ + class UserEventRejoinScope(proto.Enum): + r"""The scope of user events to be rejoined with the latest product + catalog. If the rejoining aims at reducing number of unjoined + events, set ``UserEventRejoinScope`` to ``UNJOINED_EVENTS``. If the + rejoining aims at correcting product catalog information in joined + events, set ``UserEventRejoinScope`` to ``JOINED_EVENTS``. If all + events needs to be rejoined, set ``UserEventRejoinScope`` to + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED``. + + Values: + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED (0): + Rejoin all events with the latest product + catalog, including both joined events and + unjoined events. + JOINED_EVENTS (1): + Only rejoin joined events with the latest + product catalog. + UNJOINED_EVENTS (2): + Only rejoin unjoined events with the latest + product catalog. + """ + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED = 0 + JOINED_EVENTS = 1 + UNJOINED_EVENTS = 2 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event_rejoin_scope: UserEventRejoinScope = proto.Field( + proto.ENUM, + number=2, + enum=UserEventRejoinScope, + ) + + +class RejoinUserEventsResponse(proto.Message): + r"""Response message for ``RejoinUserEvents`` method. + + Attributes: + rejoined_user_events_count (int): + Number of user events that were joined with + latest product catalog. + """ + + rejoined_user_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + + +class RejoinUserEventsMetadata(proto.Message): + r"""Metadata for ``RejoinUserEvents`` method. + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2alpha/mypy.ini b/owl-bot-staging/v2alpha/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v2alpha/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v2alpha/noxfile.py b/owl-bot-staging/v2alpha/noxfile.py new file mode 100644 index 00000000..88656981 --- /dev/null +++ b/owl-bot-staging/v2alpha/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/retail_v2alpha/', + '--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/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_async.py new file mode 100644 index 00000000..3b5a2298 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_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 AddCatalogAttribute +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_AddCatalogAttribute_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 retail_v2alpha + + +async def sample_add_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_AddCatalogAttribute_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_sync.py new file mode 100644 index 00000000..f38f9639 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_add_catalog_attribute_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 AddCatalogAttribute +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_AddCatalogAttribute_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 retail_v2alpha + + +def sample_add_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_AddCatalogAttribute_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_async.py new file mode 100644 index 00000000..5c587457 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_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 BatchRemoveCatalogAttributes +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_BatchRemoveCatalogAttributes_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 retail_v2alpha + + +async def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = await client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_BatchRemoveCatalogAttributes_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_sync.py new file mode 100644 index 00000000..ee9534f3 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_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 BatchRemoveCatalogAttributes +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_BatchRemoveCatalogAttributes_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 retail_v2alpha + + +def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_BatchRemoveCatalogAttributes_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_async.py new file mode 100644 index 00000000..9fc7b520 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_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 GetAttributesConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_GetAttributesConfig_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 retail_v2alpha + + +async def sample_get_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_GetAttributesConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_sync.py new file mode 100644 index 00000000..5929f3d0 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_attributes_config_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 GetAttributesConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_GetAttributesConfig_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 retail_v2alpha + + +def sample_get_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_GetAttributesConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_async.py new file mode 100644 index 00000000..8fff4fc6 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_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 GetCompletionConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_GetCompletionConfig_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 retail_v2alpha + + +async def sample_get_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_GetCompletionConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_sync.py new file mode 100644 index 00000000..384e335d --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_completion_config_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 GetCompletionConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_GetCompletionConfig_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 retail_v2alpha + + +def sample_get_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_GetCompletionConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_async.py new file mode 100644 index 00000000..cf486bc0 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_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 GetDefaultBranch +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_GetDefaultBranch_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 retail_v2alpha + + +async def sample_get_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetDefaultBranchRequest( + ) + + # Make the request + response = await client.get_default_branch(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_GetDefaultBranch_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_sync.py new file mode 100644 index 00000000..2e894f04 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_get_default_branch_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 GetDefaultBranch +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_GetDefaultBranch_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 retail_v2alpha + + +def sample_get_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetDefaultBranchRequest( + ) + + # Make the request + response = client.get_default_branch(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_GetDefaultBranch_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_async.py new file mode 100644 index 00000000..206a1174 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_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 ListCatalogs +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_ListCatalogs_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 retail_v2alpha + + +async def sample_list_catalogs(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2alpha_generated_CatalogService_ListCatalogs_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_sync.py new file mode 100644 index 00000000..fb919b0a --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_list_catalogs_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 ListCatalogs +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_ListCatalogs_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 retail_v2alpha + + +def sample_list_catalogs(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2alpha_generated_CatalogService_ListCatalogs_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_async.py new file mode 100644 index 00000000..88f52aa2 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_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 RemoveCatalogAttribute +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_RemoveCatalogAttribute_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 retail_v2alpha + + +async def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = await client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_RemoveCatalogAttribute_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_sync.py new file mode 100644 index 00000000..e942e0b3 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_remove_catalog_attribute_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 RemoveCatalogAttribute +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_RemoveCatalogAttribute_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 retail_v2alpha + + +def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_RemoveCatalogAttribute_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_async.py new file mode 100644 index 00000000..7e130f30 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_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 ReplaceCatalogAttribute +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_ReplaceCatalogAttribute_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 retail_v2alpha + + +async def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_ReplaceCatalogAttribute_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_sync.py new file mode 100644 index 00000000..68b6ba18 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_replace_catalog_attribute_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 ReplaceCatalogAttribute +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_ReplaceCatalogAttribute_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 retail_v2alpha + + +def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2alpha.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2alpha.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_ReplaceCatalogAttribute_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_async.py new file mode 100644 index 00000000..884a8325 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_async.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetDefaultBranch +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_SetDefaultBranch_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 retail_v2alpha + + +async def sample_set_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.SetDefaultBranchRequest( + ) + + # Make the request + await client.set_default_branch(request=request) + + +# [END retail_v2alpha_generated_CatalogService_SetDefaultBranch_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_sync.py new file mode 100644 index 00000000..15c18279 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_set_default_branch_sync.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetDefaultBranch +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_SetDefaultBranch_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 retail_v2alpha + + +def sample_set_default_branch(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.SetDefaultBranchRequest( + ) + + # Make the request + client.set_default_branch(request=request) + + +# [END retail_v2alpha_generated_CatalogService_SetDefaultBranch_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_async.py new file mode 100644 index 00000000..d7be0e40 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_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 UpdateAttributesConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_UpdateAttributesConfig_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 retail_v2alpha + + +async def sample_update_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + attributes_config = retail_v2alpha.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2alpha.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = await client.update_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_UpdateAttributesConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_sync.py new file mode 100644 index 00000000..f6d5d6f9 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_attributes_config_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 UpdateAttributesConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_UpdateAttributesConfig_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 retail_v2alpha + + +def sample_update_attributes_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + attributes_config = retail_v2alpha.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2alpha.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = client.update_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_UpdateAttributesConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_async.py new file mode 100644 index 00000000..4f656fda --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_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 UpdateCatalog +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_UpdateCatalog_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 retail_v2alpha + + +async def sample_update_catalog(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog = retail_v2alpha.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2alpha.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = await client.update_catalog(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_UpdateCatalog_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_sync.py new file mode 100644 index 00000000..4d7bdb0e --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_catalog_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 UpdateCatalog +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_UpdateCatalog_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 retail_v2alpha + + +def sample_update_catalog(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + catalog = retail_v2alpha.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2alpha.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = client.update_catalog(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_UpdateCatalog_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_async.py new file mode 100644 index 00000000..6233ddf2 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_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 UpdateCompletionConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_UpdateCompletionConfig_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 retail_v2alpha + + +async def sample_update_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceAsyncClient() + + # Initialize request argument(s) + completion_config = retail_v2alpha.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2alpha.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = await client.update_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_UpdateCompletionConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_sync.py new file mode 100644 index 00000000..8ab07b91 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_catalog_service_update_completion_config_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 UpdateCompletionConfig +# 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-retail + + +# [START retail_v2alpha_generated_CatalogService_UpdateCompletionConfig_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 retail_v2alpha + + +def sample_update_completion_config(): + # Create a client + client = retail_v2alpha.CatalogServiceClient() + + # Initialize request argument(s) + completion_config = retail_v2alpha.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2alpha.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = client.update_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CatalogService_UpdateCompletionConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_async.py new file mode 100644 index 00000000..79bb7ad3 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_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 CompleteQuery +# 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-retail + + +# [START retail_v2alpha_generated_CompletionService_CompleteQuery_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 retail_v2alpha + + +async def sample_complete_query(): + # Create a client + client = retail_v2alpha.CompletionServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = await client.complete_query(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CompletionService_CompleteQuery_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_sync.py new file mode 100644 index 00000000..c7a7713d --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_complete_query_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 CompleteQuery +# 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-retail + + +# [START retail_v2alpha_generated_CompletionService_CompleteQuery_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 retail_v2alpha + + +def sample_complete_query(): + # Create a client + client = retail_v2alpha.CompletionServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = client.complete_query(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CompletionService_CompleteQuery_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_async.py new file mode 100644 index 00000000..7836d4f0 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportCompletionData +# 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-retail + + +# [START retail_v2alpha_generated_CompletionService_ImportCompletionData_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 retail_v2alpha + + +async def sample_import_completion_data(): + # Create a client + client = retail_v2alpha.CompletionServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2alpha.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CompletionService_ImportCompletionData_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_sync.py new file mode 100644 index 00000000..0e3197bb --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_completion_service_import_completion_data_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportCompletionData +# 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-retail + + +# [START retail_v2alpha_generated_CompletionService_ImportCompletionData_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 retail_v2alpha + + +def sample_import_completion_data(): + # Create a client + client = retail_v2alpha.CompletionServiceClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2alpha.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_CompletionService_ImportCompletionData_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_async.py new file mode 100644 index 00000000..d54595ec --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_async.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_CreateControl_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 retail_v2alpha + + +async def sample_create_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = await client.create_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ControlService_CreateControl_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_sync.py new file mode 100644 index 00000000..e1d592e2 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_create_control_sync.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_CreateControl_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 retail_v2alpha + + +def sample_create_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = client.create_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ControlService_CreateControl_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_async.py new file mode 100644 index 00000000..1d24e00b --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_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 DeleteControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_DeleteControl_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 retail_v2alpha + + +async def sample_delete_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteControlRequest( + name="name_value", + ) + + # Make the request + await client.delete_control(request=request) + + +# [END retail_v2alpha_generated_ControlService_DeleteControl_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_sync.py new file mode 100644 index 00000000..c7ad7acc --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_delete_control_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 DeleteControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_DeleteControl_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 retail_v2alpha + + +def sample_delete_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteControlRequest( + name="name_value", + ) + + # Make the request + client.delete_control(request=request) + + +# [END retail_v2alpha_generated_ControlService_DeleteControl_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_async.py new file mode 100644 index 00000000..6ec07291 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_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 GetControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_GetControl_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 retail_v2alpha + + +async def sample_get_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetControlRequest( + name="name_value", + ) + + # Make the request + response = await client.get_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ControlService_GetControl_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_sync.py new file mode 100644 index 00000000..fe0a4520 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_get_control_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 GetControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_GetControl_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 retail_v2alpha + + +def sample_get_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetControlRequest( + name="name_value", + ) + + # Make the request + response = client.get_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ControlService_GetControl_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_async.py new file mode 100644 index 00000000..1379980c --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_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 ListControls +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_ListControls_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 retail_v2alpha + + +async def sample_list_controls(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2alpha_generated_ControlService_ListControls_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_sync.py new file mode 100644 index 00000000..46ec4814 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_list_controls_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 ListControls +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_ListControls_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 retail_v2alpha + + +def sample_list_controls(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2alpha_generated_ControlService_ListControls_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_async.py new file mode 100644 index 00000000..32336d2b --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_UpdateControl_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 retail_v2alpha + + +async def sample_update_control(): + # Create a client + client = retail_v2alpha.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateControlRequest( + control=control, + ) + + # Make the request + response = await client.update_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ControlService_UpdateControl_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_sync.py new file mode 100644 index 00000000..62c3c525 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_control_service_update_control_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateControl +# 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-retail + + +# [START retail_v2alpha_generated_ControlService_UpdateControl_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 retail_v2alpha + + +def sample_update_control(): + # Create a client + client = retail_v2alpha.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2alpha.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateControlRequest( + control=control, + ) + + # Make the request + response = client.update_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ControlService_UpdateControl_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py new file mode 100644 index 00000000..21f541c0 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateMerchantCenterAccountLink +# 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-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_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 retail_v2alpha + + +async def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py new file mode 100644 index 00000000..096206ae --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateMerchantCenterAccountLink +# 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-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_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 retail_v2alpha + + +def sample_create_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + merchant_center_account_link = retail_v2alpha.MerchantCenterAccountLink() + merchant_center_account_link.merchant_center_account_id = 2730 + merchant_center_account_link.branch_id = "branch_id_value" + + request = retail_v2alpha.CreateMerchantCenterAccountLinkRequest( + parent="parent_value", + merchant_center_account_link=merchant_center_account_link, + ) + + # Make the request + operation = client.create_merchant_center_account_link(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py new file mode 100644 index 00000000..392863c9 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_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 DeleteMerchantCenterAccountLink +# 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-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_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 retail_v2alpha + + +async def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + await client.delete_merchant_center_account_link(request=request) + + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py new file mode 100644 index 00000000..cbfa514c --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_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 DeleteMerchantCenterAccountLink +# 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-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_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 retail_v2alpha + + +def sample_delete_merchant_center_account_link(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteMerchantCenterAccountLinkRequest( + name="name_value", + ) + + # Make the request + client.delete_merchant_center_account_link(request=request) + + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py new file mode 100644 index 00000000..c5d62c08 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_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 ListMerchantCenterAccountLinks +# 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-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_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 retail_v2alpha + + +async def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = await client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py new file mode 100644 index 00000000..b97332f3 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_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 ListMerchantCenterAccountLinks +# 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-retail + + +# [START retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_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 retail_v2alpha + + +def sample_list_merchant_center_account_links(): + # Create a client + client = retail_v2alpha.MerchantCenterAccountLinkServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListMerchantCenterAccountLinksRequest( + parent="parent_value", + ) + + # Make the request + response = client.list_merchant_center_account_links(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_async.py new file mode 100644 index 00000000..93a89dff --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_async.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_CreateModel_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 retail_v2alpha + + +async def sample_create_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_CreateModel_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_sync.py new file mode 100644 index 00000000..9bdfec77 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_create_model_sync.py @@ -0,0 +1,65 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_CreateModel_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 retail_v2alpha + + +def sample_create_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_CreateModel_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_async.py new file mode 100644 index 00000000..9b84f6fc --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_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 DeleteModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_DeleteModel_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 retail_v2alpha + + +async def sample_delete_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + +# [END retail_v2alpha_generated_ModelService_DeleteModel_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_sync.py new file mode 100644 index 00000000..ed03009e --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_delete_model_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 DeleteModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_DeleteModel_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 retail_v2alpha + + +def sample_delete_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + +# [END retail_v2alpha_generated_ModelService_DeleteModel_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_async.py new file mode 100644 index 00000000..519c54bb --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_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 GetModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_GetModel_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 retail_v2alpha + + +async def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_GetModel_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_sync.py new file mode 100644 index 00000000..628299ee --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_get_model_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 GetModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_GetModel_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 retail_v2alpha + + +def sample_get_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_GetModel_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_async.py new file mode 100644 index 00000000..bfca9952 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_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 ListModels +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_ListModels_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 retail_v2alpha + + +async def sample_list_models(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2alpha_generated_ModelService_ListModels_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_sync.py new file mode 100644 index 00000000..1fa435f8 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_list_models_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 ListModels +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_ListModels_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 retail_v2alpha + + +def sample_list_models(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2alpha_generated_ModelService_ListModels_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_async.py new file mode 100644 index 00000000..8ea8893a --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_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 PauseModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_PauseModel_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 retail_v2alpha + + +async def sample_pause_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_PauseModel_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_sync.py new file mode 100644 index 00000000..2a2eeeae --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_pause_model_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 PauseModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_PauseModel_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 retail_v2alpha + + +def sample_pause_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_PauseModel_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_async.py new file mode 100644 index 00000000..8b5d6f29 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_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 ResumeModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_ResumeModel_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 retail_v2alpha + + +async def sample_resume_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_ResumeModel_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_sync.py new file mode 100644 index 00000000..4665bcd3 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_resume_model_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 ResumeModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_ResumeModel_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 retail_v2alpha + + +def sample_resume_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_ResumeModel_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_async.py new file mode 100644 index 00000000..a6999c06 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_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 TuneModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_TuneModel_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 retail_v2alpha + + +async def sample_tune_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_TuneModel_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_sync.py new file mode 100644 index 00000000..cf3798b9 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_tune_model_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 TuneModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_TuneModel_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 retail_v2alpha + + +def sample_tune_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_TuneModel_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_async.py new file mode 100644 index 00000000..04f49540 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_async.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_UpdateModel_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 retail_v2alpha + + +async def sample_update_model(): + # Create a client + client = retail_v2alpha.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_UpdateModel_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_sync.py new file mode 100644 index 00000000..0669b56c --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_model_service_update_model_sync.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateModel +# 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-retail + + +# [START retail_v2alpha_generated_ModelService_UpdateModel_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 retail_v2alpha + + +def sample_update_model(): + # Create a client + client = retail_v2alpha.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2alpha.Model() + model.page_optimization_config.page_optimization_event_type = "page_optimization_event_type_value" + model.page_optimization_config.panels.candidates.serving_config_id = "serving_config_id_value" + model.page_optimization_config.panels.default_candidate.serving_config_id = "serving_config_id_value" + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2alpha.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ModelService_UpdateModel_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_async.py new file mode 100644 index 00000000..f5809861 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Predict +# 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-retail + + +# [START retail_v2alpha_generated_PredictionService_Predict_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 retail_v2alpha + + +async def sample_predict(): + # Create a client + client = retail_v2alpha.PredictionServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = await client.predict(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_PredictionService_Predict_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_sync.py new file mode 100644 index 00000000..7f0a5630 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_prediction_service_predict_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Predict +# 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-retail + + +# [START retail_v2alpha_generated_PredictionService_Predict_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 retail_v2alpha + + +def sample_predict(): + # Create a client + client = retail_v2alpha.PredictionServiceClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = client.predict(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_PredictionService_Predict_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_async.py new file mode 100644 index 00000000..3c856925 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 AddFulfillmentPlaces +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_AddFulfillmentPlaces_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 retail_v2alpha + + +async def sample_add_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_AddFulfillmentPlaces_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_sync.py new file mode 100644 index 00000000..c034a478 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_fulfillment_places_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 AddFulfillmentPlaces +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_AddFulfillmentPlaces_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 retail_v2alpha + + +def sample_add_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_AddFulfillmentPlaces_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_async.py new file mode 100644 index 00000000..60395c40 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_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 AddLocalInventories +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_AddLocalInventories_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 retail_v2alpha + + +async def sample_add_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_AddLocalInventories_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_sync.py new file mode 100644 index 00000000..ceca6adb --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_add_local_inventories_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 AddLocalInventories +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_AddLocalInventories_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 retail_v2alpha + + +def sample_add_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_AddLocalInventories_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_async.py new file mode 100644 index 00000000..8480150e --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +async def sample_create_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_CreateProduct_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_sync.py new file mode 100644 index 00000000..5236a01a --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_create_product_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +def sample_create_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_CreateProduct_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_delete_product_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_delete_product_async.py new file mode 100644 index 00000000..d5b95eee --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +async def sample_delete_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + +# [END retail_v2alpha_generated_ProductService_DeleteProduct_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_delete_product_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_delete_product_sync.py new file mode 100644 index 00000000..09907332 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +def sample_delete_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + +# [END retail_v2alpha_generated_ProductService_DeleteProduct_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_get_product_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_get_product_async.py new file mode 100644 index 00000000..b5d42b1c --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +async def sample_get_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_GetProduct_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_get_product_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_get_product_sync.py new file mode 100644 index 00000000..87eb24fd --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +def sample_get_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_GetProduct_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_async.py new file mode 100644 index 00000000..4af9fcef --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_async.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportProducts +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_ImportProducts_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 retail_v2alpha + + +async def sample_import_products(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2alpha.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_ImportProducts_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_sync.py new file mode 100644 index 00000000..d4ad01c1 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_import_products_sync.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportProducts +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_ImportProducts_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 retail_v2alpha + + +def sample_import_products(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2alpha.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_ImportProducts_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_list_products_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_list_products_async.py new file mode 100644 index 00000000..cb8b98d9 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +async def sample_list_products(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.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 retail_v2alpha_generated_ProductService_ListProducts_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_list_products_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_list_products_sync.py new file mode 100644 index 00000000..ecf979a1 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +def sample_list_products(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.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 retail_v2alpha_generated_ProductService_ListProducts_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_async.py new file mode 100644 index 00000000..e0b7d299 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +async def sample_purge_products(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeProductsRequest( + parent="parent_value", + filter="filter_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 retail_v2alpha_generated_ProductService_PurgeProducts_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_sync.py new file mode 100644 index 00000000..50bb1eb5 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_purge_products_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +def sample_purge_products(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeProductsRequest( + parent="parent_value", + filter="filter_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 retail_v2alpha_generated_ProductService_PurgeProducts_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_async.py new file mode 100644 index 00000000..b338ea97 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveFulfillmentPlaces +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_RemoveFulfillmentPlaces_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 retail_v2alpha + + +async def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_RemoveFulfillmentPlaces_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_sync.py new file mode 100644 index 00000000..4aa2dacc --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_fulfillment_places_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveFulfillmentPlaces +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_RemoveFulfillmentPlaces_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 retail_v2alpha + + +def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_RemoveFulfillmentPlaces_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_async.py new file mode 100644 index 00000000..44f9dddf --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveLocalInventories +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_RemoveLocalInventories_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 retail_v2alpha + + +async def sample_remove_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_RemoveLocalInventories_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_sync.py new file mode 100644 index 00000000..24c7c684 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_remove_local_inventories_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveLocalInventories +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_RemoveLocalInventories_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 retail_v2alpha + + +def sample_remove_local_inventories(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_RemoveLocalInventories_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_async.py new file mode 100644 index 00000000..bf175170 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_async.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetInventory +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_SetInventory_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 retail_v2alpha + + +async def sample_set_inventory(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + inventory = retail_v2alpha.Product() + inventory.title = "title_value" + + request = retail_v2alpha.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_SetInventory_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_sync.py new file mode 100644 index 00000000..c318e77d --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_set_inventory_sync.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetInventory +# 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-retail + + +# [START retail_v2alpha_generated_ProductService_SetInventory_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 retail_v2alpha + + +def sample_set_inventory(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + inventory = retail_v2alpha.Product() + inventory.title = "title_value" + + request = retail_v2alpha.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_SetInventory_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_async.py new file mode 100644 index 00000000..f5bdc5ac --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_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 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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +async def sample_update_product(): + # Create a client + client = retail_v2alpha.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.UpdateProductRequest( + product=product, + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_UpdateProduct_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_sync.py new file mode 100644 index 00000000..86d4f0b3 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_product_service_update_product_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 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-retail + + +# [START retail_v2alpha_generated_ProductService_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 retail_v2alpha + + +def sample_update_product(): + # Create a client + client = retail_v2alpha.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2alpha.Product() + product.title = "title_value" + + request = retail_v2alpha.UpdateProductRequest( + product=product, + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ProductService_UpdateProduct_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_async.py new file mode 100644 index 00000000..54e9cd6a --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Search +# 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-retail + + +# [START retail_v2alpha_generated_SearchService_Search_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 retail_v2alpha + + +async def sample_search(): + # Create a client + client = retail_v2alpha.SearchServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2alpha_generated_SearchService_Search_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_sync.py new file mode 100644 index 00000000..8f04ef65 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_search_service_search_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Search +# 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-retail + + +# [START retail_v2alpha_generated_SearchService_Search_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 retail_v2alpha + + +def sample_search(): + # Create a client + client = retail_v2alpha.SearchServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2alpha_generated_SearchService_Search_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_async.py new file mode 100644 index 00000000..8ff5967f --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_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 AddControl +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_AddControl_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 retail_v2alpha + + +async def sample_add_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.add_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_AddControl_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_sync.py new file mode 100644 index 00000000..aaec2750 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_add_control_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 AddControl +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_AddControl_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 retail_v2alpha + + +def sample_add_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.add_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_AddControl_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_async.py new file mode 100644 index 00000000..3e3e08b2 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_CreateServingConfig_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 retail_v2alpha + + +async def sample_create_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = await client.create_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_CreateServingConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_sync.py new file mode 100644 index 00000000..0d14f90c --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_create_serving_config_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_CreateServingConfig_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 retail_v2alpha + + +def sample_create_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = client.create_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_CreateServingConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_async.py new file mode 100644 index 00000000..15179fad --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_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 DeleteServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_DeleteServingConfig_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 retail_v2alpha + + +async def sample_delete_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_serving_config(request=request) + + +# [END retail_v2alpha_generated_ServingConfigService_DeleteServingConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_sync.py new file mode 100644 index 00000000..2e20a6fd --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_delete_serving_config_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 DeleteServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_DeleteServingConfig_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 retail_v2alpha + + +def sample_delete_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_serving_config(request=request) + + +# [END retail_v2alpha_generated_ServingConfigService_DeleteServingConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_async.py new file mode 100644 index 00000000..d4caab21 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_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 GetServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_GetServingConfig_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 retail_v2alpha + + +async def sample_get_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_GetServingConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_sync.py new file mode 100644 index 00000000..b2dac9e0 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_get_serving_config_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 GetServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_GetServingConfig_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 retail_v2alpha + + +def sample_get_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_GetServingConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_async.py new file mode 100644 index 00000000..387bcd7b --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_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 ListServingConfigs +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_ListServingConfigs_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 retail_v2alpha + + +async def sample_list_serving_configs(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_ListServingConfigs_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_sync.py new file mode 100644 index 00000000..ca70753b --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_list_serving_configs_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 ListServingConfigs +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_ListServingConfigs_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 retail_v2alpha + + +def sample_list_serving_configs(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_ListServingConfigs_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_async.py new file mode 100644 index 00000000..83488170 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_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 RemoveControl +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_RemoveControl_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 retail_v2alpha + + +async def sample_remove_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.remove_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_RemoveControl_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_sync.py new file mode 100644 index 00000000..225efb07 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_remove_control_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 RemoveControl +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_RemoveControl_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 retail_v2alpha + + +def sample_remove_control(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.remove_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_RemoveControl_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_async.py new file mode 100644 index 00000000..4bdeb98c --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_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 UpdateServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_UpdateServingConfig_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 retail_v2alpha + + +async def sample_update_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = await client.update_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_UpdateServingConfig_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_sync.py new file mode 100644 index 00000000..c51af681 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_serving_config_service_update_serving_config_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 UpdateServingConfig +# 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-retail + + +# [START retail_v2alpha_generated_ServingConfigService_UpdateServingConfig_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 retail_v2alpha + + +def sample_update_serving_config(): + # Create a client + client = retail_v2alpha.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2alpha.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2alpha.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = client.update_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_ServingConfigService_UpdateServingConfig_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_async.py new file mode 100644 index 00000000..a292d25c --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CollectUserEvent +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_CollectUserEvent_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 retail_v2alpha + + +async def sample_collect_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = await client.collect_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_CollectUserEvent_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_sync.py new file mode 100644 index 00000000..1f7e2cd8 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_collect_user_event_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CollectUserEvent +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_CollectUserEvent_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 retail_v2alpha + + +def sample_collect_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = client.collect_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_CollectUserEvent_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_async.py new file mode 100644 index 00000000..a94ab054 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportUserEvents +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_ImportUserEvents_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 retail_v2alpha + + +async def sample_import_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2alpha.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_ImportUserEvents_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_sync.py new file mode 100644 index 00000000..4e0c298e --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_import_user_events_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportUserEvents +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_ImportUserEvents_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 retail_v2alpha + + +def sample_import_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + input_config = retail_v2alpha.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2alpha.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_ImportUserEvents_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_async.py new file mode 100644 index 00000000..261c825d --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 PurgeUserEvents +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_PurgeUserEvents_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 retail_v2alpha + + +async def sample_purge_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_PurgeUserEvents_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_sync.py new file mode 100644 index 00000000..cbbec198 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_purge_user_events_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 PurgeUserEvents +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_PurgeUserEvents_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 retail_v2alpha + + +def sample_purge_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_PurgeUserEvents_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_async.py new file mode 100644 index 00000000..0924ee2e --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_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 RejoinUserEvents +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_RejoinUserEvents_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 retail_v2alpha + + +async def sample_rejoin_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2alpha.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_RejoinUserEvents_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_sync.py new file mode 100644 index 00000000..df73f755 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_rejoin_user_events_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 RejoinUserEvents +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_RejoinUserEvents_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 retail_v2alpha + + +def sample_rejoin_user_events(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2alpha.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_RejoinUserEvents_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_async.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_async.py new file mode 100644 index 00000000..27c5e9e6 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 WriteUserEvent +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_WriteUserEvent_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 retail_v2alpha + + +async def sample_write_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = await client.write_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_WriteUserEvent_async] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_sync.py b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_sync.py new file mode 100644 index 00000000..cf2187e6 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/retail_v2alpha_generated_user_event_service_write_user_event_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 WriteUserEvent +# 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-retail + + +# [START retail_v2alpha_generated_UserEventService_WriteUserEvent_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 retail_v2alpha + + +def sample_write_user_event(): + # Create a client + client = retail_v2alpha.UserEventServiceClient() + + # Initialize request argument(s) + user_event = retail_v2alpha.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2alpha.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = client.write_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2alpha_generated_UserEventService_WriteUserEvent_sync] diff --git a/owl-bot-staging/v2alpha/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json b/owl-bot-staging/v2alpha/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json new file mode 100644 index 00000000..55845bb0 --- /dev/null +++ b/owl-bot-staging/v2alpha/samples/generated_samples/snippet_metadata_google.cloud.retail.v2alpha.json @@ -0,0 +1,9003 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.retail.v2alpha", + "version": "v2alpha" + } + ], + "language": "PYTHON", + "name": "google-cloud-retail", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.add_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.AddCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "AddCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.AttributesConfig", + "shortName": "add_catalog_attribute" + }, + "description": "Sample for AddCatalogAttribute", + "file": "retail_v2alpha_generated_catalog_service_add_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_AddCatalogAttribute_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": "retail_v2alpha_generated_catalog_service_add_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.add_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.AddCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "AddCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.AttributesConfig", + "shortName": "add_catalog_attribute" + }, + "description": "Sample for AddCatalogAttribute", + "file": "retail_v2alpha_generated_catalog_service_add_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_AddCatalogAttribute_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": "retail_v2alpha_generated_catalog_service_add_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.batch_remove_catalog_attributes", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "BatchRemoveCatalogAttributes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesResponse", + "shortName": "batch_remove_catalog_attributes" + }, + "description": "Sample for BatchRemoveCatalogAttributes", + "file": "retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_BatchRemoveCatalogAttributes_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.batch_remove_catalog_attributes", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.BatchRemoveCatalogAttributes", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "BatchRemoveCatalogAttributes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.BatchRemoveCatalogAttributesResponse", + "shortName": "batch_remove_catalog_attributes" + }, + "description": "Sample for BatchRemoveCatalogAttributes", + "file": "retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_BatchRemoveCatalogAttributes_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_batch_remove_catalog_attributes_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.get_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.GetAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetAttributesConfigRequest" + }, + { + "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.retail_v2alpha.types.AttributesConfig", + "shortName": "get_attributes_config" + }, + "description": "Sample for GetAttributesConfig", + "file": "retail_v2alpha_generated_catalog_service_get_attributes_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_GetAttributesConfig_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": "retail_v2alpha_generated_catalog_service_get_attributes_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.get_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.GetAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetAttributesConfigRequest" + }, + { + "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.retail_v2alpha.types.AttributesConfig", + "shortName": "get_attributes_config" + }, + "description": "Sample for GetAttributesConfig", + "file": "retail_v2alpha_generated_catalog_service_get_attributes_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_GetAttributesConfig_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": "retail_v2alpha_generated_catalog_service_get_attributes_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.get_completion_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.GetCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetCompletionConfigRequest" + }, + { + "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.retail_v2alpha.types.CompletionConfig", + "shortName": "get_completion_config" + }, + "description": "Sample for GetCompletionConfig", + "file": "retail_v2alpha_generated_catalog_service_get_completion_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_GetCompletionConfig_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": "retail_v2alpha_generated_catalog_service_get_completion_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.get_completion_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.GetCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetCompletionConfigRequest" + }, + { + "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.retail_v2alpha.types.CompletionConfig", + "shortName": "get_completion_config" + }, + "description": "Sample for GetCompletionConfig", + "file": "retail_v2alpha_generated_catalog_service_get_completion_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_GetCompletionConfig_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": "retail_v2alpha_generated_catalog_service_get_completion_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.get_default_branch", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.GetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.GetDefaultBranchResponse", + "shortName": "get_default_branch" + }, + "description": "Sample for GetDefaultBranch", + "file": "retail_v2alpha_generated_catalog_service_get_default_branch_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_GetDefaultBranch_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": "retail_v2alpha_generated_catalog_service_get_default_branch_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.get_default_branch", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.GetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.GetDefaultBranchResponse", + "shortName": "get_default_branch" + }, + "description": "Sample for GetDefaultBranch", + "file": "retail_v2alpha_generated_catalog_service_get_default_branch_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_GetDefaultBranch_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": "retail_v2alpha_generated_catalog_service_get_default_branch_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.list_catalogs", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.ListCatalogs", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ListCatalogs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListCatalogsRequest" + }, + { + "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.retail_v2alpha.services.catalog_service.pagers.ListCatalogsAsyncPager", + "shortName": "list_catalogs" + }, + "description": "Sample for ListCatalogs", + "file": "retail_v2alpha_generated_catalog_service_list_catalogs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_ListCatalogs_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": "retail_v2alpha_generated_catalog_service_list_catalogs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.list_catalogs", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.ListCatalogs", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ListCatalogs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListCatalogsRequest" + }, + { + "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.retail_v2alpha.services.catalog_service.pagers.ListCatalogsPager", + "shortName": "list_catalogs" + }, + "description": "Sample for ListCatalogs", + "file": "retail_v2alpha_generated_catalog_service_list_catalogs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_ListCatalogs_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": "retail_v2alpha_generated_catalog_service_list_catalogs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.remove_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.RemoveCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "RemoveCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.AttributesConfig", + "shortName": "remove_catalog_attribute" + }, + "description": "Sample for RemoveCatalogAttribute", + "file": "retail_v2alpha_generated_catalog_service_remove_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_RemoveCatalogAttribute_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_remove_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.remove_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.RemoveCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "RemoveCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.AttributesConfig", + "shortName": "remove_catalog_attribute" + }, + "description": "Sample for RemoveCatalogAttribute", + "file": "retail_v2alpha_generated_catalog_service_remove_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_RemoveCatalogAttribute_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_remove_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.replace_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.ReplaceCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ReplaceCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ReplaceCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.AttributesConfig", + "shortName": "replace_catalog_attribute" + }, + "description": "Sample for ReplaceCatalogAttribute", + "file": "retail_v2alpha_generated_catalog_service_replace_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_ReplaceCatalogAttribute_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": "retail_v2alpha_generated_catalog_service_replace_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.replace_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.ReplaceCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ReplaceCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ReplaceCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.AttributesConfig", + "shortName": "replace_catalog_attribute" + }, + "description": "Sample for ReplaceCatalogAttribute", + "file": "retail_v2alpha_generated_catalog_service_replace_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_ReplaceCatalogAttribute_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": "retail_v2alpha_generated_catalog_service_replace_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.set_default_branch", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.SetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "SetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.SetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "set_default_branch" + }, + "description": "Sample for SetDefaultBranch", + "file": "retail_v2alpha_generated_catalog_service_set_default_branch_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_SetDefaultBranch_async", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_set_default_branch_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.set_default_branch", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.SetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "SetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.SetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "set_default_branch" + }, + "description": "Sample for SetDefaultBranch", + "file": "retail_v2alpha_generated_catalog_service_set_default_branch_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_SetDefaultBranch_sync", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_set_default_branch_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.update_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.UpdateAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateAttributesConfigRequest" + }, + { + "name": "attributes_config", + "type": "google.cloud.retail_v2alpha.types.AttributesConfig" + }, + { + "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.retail_v2alpha.types.AttributesConfig", + "shortName": "update_attributes_config" + }, + "description": "Sample for UpdateAttributesConfig", + "file": "retail_v2alpha_generated_catalog_service_update_attributes_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_UpdateAttributesConfig_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_update_attributes_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.update_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.UpdateAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateAttributesConfigRequest" + }, + { + "name": "attributes_config", + "type": "google.cloud.retail_v2alpha.types.AttributesConfig" + }, + { + "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.retail_v2alpha.types.AttributesConfig", + "shortName": "update_attributes_config" + }, + "description": "Sample for UpdateAttributesConfig", + "file": "retail_v2alpha_generated_catalog_service_update_attributes_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_UpdateAttributesConfig_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_update_attributes_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.update_catalog", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.UpdateCatalog", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCatalog" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateCatalogRequest" + }, + { + "name": "catalog", + "type": "google.cloud.retail_v2alpha.types.Catalog" + }, + { + "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.retail_v2alpha.types.Catalog", + "shortName": "update_catalog" + }, + "description": "Sample for UpdateCatalog", + "file": "retail_v2alpha_generated_catalog_service_update_catalog_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_UpdateCatalog_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": "retail_v2alpha_generated_catalog_service_update_catalog_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.update_catalog", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.UpdateCatalog", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCatalog" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateCatalogRequest" + }, + { + "name": "catalog", + "type": "google.cloud.retail_v2alpha.types.Catalog" + }, + { + "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.retail_v2alpha.types.Catalog", + "shortName": "update_catalog" + }, + "description": "Sample for UpdateCatalog", + "file": "retail_v2alpha_generated_catalog_service_update_catalog_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_UpdateCatalog_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": "retail_v2alpha_generated_catalog_service_update_catalog_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceAsyncClient.update_completion_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.UpdateCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateCompletionConfigRequest" + }, + { + "name": "completion_config", + "type": "google.cloud.retail_v2alpha.types.CompletionConfig" + }, + { + "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.retail_v2alpha.types.CompletionConfig", + "shortName": "update_completion_config" + }, + "description": "Sample for UpdateCompletionConfig", + "file": "retail_v2alpha_generated_catalog_service_update_completion_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_UpdateCompletionConfig_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_update_completion_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CatalogServiceClient.update_completion_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.CatalogService.UpdateCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateCompletionConfigRequest" + }, + { + "name": "completion_config", + "type": "google.cloud.retail_v2alpha.types.CompletionConfig" + }, + { + "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.retail_v2alpha.types.CompletionConfig", + "shortName": "update_completion_config" + }, + "description": "Sample for UpdateCompletionConfig", + "file": "retail_v2alpha_generated_catalog_service_update_completion_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CatalogService_UpdateCompletionConfig_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_catalog_service_update_completion_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CompletionServiceAsyncClient", + "shortName": "CompletionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CompletionServiceAsyncClient.complete_query", + "method": { + "fullName": "google.cloud.retail.v2alpha.CompletionService.CompleteQuery", + "service": { + "fullName": "google.cloud.retail.v2alpha.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "CompleteQuery" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CompleteQueryRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.CompleteQueryResponse", + "shortName": "complete_query" + }, + "description": "Sample for CompleteQuery", + "file": "retail_v2alpha_generated_completion_service_complete_query_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CompletionService_CompleteQuery_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_completion_service_complete_query_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CompletionServiceClient", + "shortName": "CompletionServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CompletionServiceClient.complete_query", + "method": { + "fullName": "google.cloud.retail.v2alpha.CompletionService.CompleteQuery", + "service": { + "fullName": "google.cloud.retail.v2alpha.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "CompleteQuery" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CompleteQueryRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.CompleteQueryResponse", + "shortName": "complete_query" + }, + "description": "Sample for CompleteQuery", + "file": "retail_v2alpha_generated_completion_service_complete_query_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CompletionService_CompleteQuery_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_completion_service_complete_query_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.CompletionServiceAsyncClient", + "shortName": "CompletionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.CompletionServiceAsyncClient.import_completion_data", + "method": { + "fullName": "google.cloud.retail.v2alpha.CompletionService.ImportCompletionData", + "service": { + "fullName": "google.cloud.retail.v2alpha.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "ImportCompletionData" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ImportCompletionDataRequest" + }, + { + "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_completion_data" + }, + "description": "Sample for ImportCompletionData", + "file": "retail_v2alpha_generated_completion_service_import_completion_data_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CompletionService_ImportCompletionData_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_completion_service_import_completion_data_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.CompletionServiceClient", + "shortName": "CompletionServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.CompletionServiceClient.import_completion_data", + "method": { + "fullName": "google.cloud.retail.v2alpha.CompletionService.ImportCompletionData", + "service": { + "fullName": "google.cloud.retail.v2alpha.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "ImportCompletionData" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ImportCompletionDataRequest" + }, + { + "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_completion_data" + }, + "description": "Sample for ImportCompletionData", + "file": "retail_v2alpha_generated_completion_service_import_completion_data_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_CompletionService_ImportCompletionData_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_completion_service_import_completion_data_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient.create_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.CreateControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "CreateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateControlRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "control", + "type": "google.cloud.retail_v2alpha.types.Control" + }, + { + "name": "control_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.retail_v2alpha.types.Control", + "shortName": "create_control" + }, + "description": "Sample for CreateControl", + "file": "retail_v2alpha_generated_control_service_create_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_CreateControl_async", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 52, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 53, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_control_service_create_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient.create_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.CreateControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "CreateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateControlRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "control", + "type": "google.cloud.retail_v2alpha.types.Control" + }, + { + "name": "control_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.retail_v2alpha.types.Control", + "shortName": "create_control" + }, + "description": "Sample for CreateControl", + "file": "retail_v2alpha_generated_control_service_create_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_CreateControl_sync", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 52, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 53, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_control_service_create_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient.delete_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.DeleteControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "DeleteControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteControlRequest" + }, + { + "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_control" + }, + "description": "Sample for DeleteControl", + "file": "retail_v2alpha_generated_control_service_delete_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_DeleteControl_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": "retail_v2alpha_generated_control_service_delete_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient.delete_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.DeleteControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "DeleteControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteControlRequest" + }, + { + "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_control" + }, + "description": "Sample for DeleteControl", + "file": "retail_v2alpha_generated_control_service_delete_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_DeleteControl_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": "retail_v2alpha_generated_control_service_delete_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient.get_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.GetControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "GetControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetControlRequest" + }, + { + "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.retail_v2alpha.types.Control", + "shortName": "get_control" + }, + "description": "Sample for GetControl", + "file": "retail_v2alpha_generated_control_service_get_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_GetControl_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": "retail_v2alpha_generated_control_service_get_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient.get_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.GetControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "GetControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetControlRequest" + }, + { + "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.retail_v2alpha.types.Control", + "shortName": "get_control" + }, + "description": "Sample for GetControl", + "file": "retail_v2alpha_generated_control_service_get_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_GetControl_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": "retail_v2alpha_generated_control_service_get_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient.list_controls", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.ListControls", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "ListControls" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListControlsRequest" + }, + { + "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.retail_v2alpha.services.control_service.pagers.ListControlsAsyncPager", + "shortName": "list_controls" + }, + "description": "Sample for ListControls", + "file": "retail_v2alpha_generated_control_service_list_controls_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_ListControls_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": "retail_v2alpha_generated_control_service_list_controls_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient.list_controls", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.ListControls", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "ListControls" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListControlsRequest" + }, + { + "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.retail_v2alpha.services.control_service.pagers.ListControlsPager", + "shortName": "list_controls" + }, + "description": "Sample for ListControls", + "file": "retail_v2alpha_generated_control_service_list_controls_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_ListControls_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": "retail_v2alpha_generated_control_service_list_controls_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceAsyncClient.update_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.UpdateControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "UpdateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateControlRequest" + }, + { + "name": "control", + "type": "google.cloud.retail_v2alpha.types.Control" + }, + { + "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.retail_v2alpha.types.Control", + "shortName": "update_control" + }, + "description": "Sample for UpdateControl", + "file": "retail_v2alpha_generated_control_service_update_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_UpdateControl_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_control_service_update_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ControlServiceClient.update_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ControlService.UpdateControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ControlService", + "shortName": "ControlService" + }, + "shortName": "UpdateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateControlRequest" + }, + { + "name": "control", + "type": "google.cloud.retail_v2alpha.types.Control" + }, + { + "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.retail_v2alpha.types.Control", + "shortName": "update_control" + }, + "description": "Sample for UpdateControl", + "file": "retail_v2alpha_generated_control_service_update_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ControlService_UpdateControl_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_control_service_update_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient", + "shortName": "MerchantCenterAccountLinkServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient.create_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "CreateMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "merchant_center_account_link", + "type": "google.cloud.retail_v2alpha.types.MerchantCenterAccountLink" + }, + { + "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": "create_merchant_center_account_link" + }, + "description": "Sample for CreateMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient", + "shortName": "MerchantCenterAccountLinkServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient.create_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.CreateMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "CreateMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateMerchantCenterAccountLinkRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "merchant_center_account_link", + "type": "google.cloud.retail_v2alpha.types.MerchantCenterAccountLink" + }, + { + "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": "create_merchant_center_account_link" + }, + "description": "Sample for CreateMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_CreateMerchantCenterAccountLink_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_merchant_center_account_link_service_create_merchant_center_account_link_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient", + "shortName": "MerchantCenterAccountLinkServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient.delete_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "DeleteMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest" + }, + { + "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_merchant_center_account_link" + }, + "description": "Sample for DeleteMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_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": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient", + "shortName": "MerchantCenterAccountLinkServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient.delete_merchant_center_account_link", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.DeleteMerchantCenterAccountLink", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "DeleteMerchantCenterAccountLink" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteMerchantCenterAccountLinkRequest" + }, + { + "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_merchant_center_account_link" + }, + "description": "Sample for DeleteMerchantCenterAccountLink", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_DeleteMerchantCenterAccountLink_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": "retail_v2alpha_generated_merchant_center_account_link_service_delete_merchant_center_account_link_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient", + "shortName": "MerchantCenterAccountLinkServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceAsyncClient.list_merchant_center_account_links", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "ListMerchantCenterAccountLinks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest" + }, + { + "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.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse", + "shortName": "list_merchant_center_account_links" + }, + "description": "Sample for ListMerchantCenterAccountLinks", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_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": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient", + "shortName": "MerchantCenterAccountLinkServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.MerchantCenterAccountLinkServiceClient.list_merchant_center_account_links", + "method": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService.ListMerchantCenterAccountLinks", + "service": { + "fullName": "google.cloud.retail.v2alpha.MerchantCenterAccountLinkService", + "shortName": "MerchantCenterAccountLinkService" + }, + "shortName": "ListMerchantCenterAccountLinks" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListMerchantCenterAccountLinksRequest" + }, + { + "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.retail_v2alpha.types.ListMerchantCenterAccountLinksResponse", + "shortName": "list_merchant_center_account_links" + }, + "description": "Sample for ListMerchantCenterAccountLinks", + "file": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_MerchantCenterAccountLinkService_ListMerchantCenterAccountLinks_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": "retail_v2alpha_generated_merchant_center_account_link_service_list_merchant_center_account_links_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2alpha.types.Model" + }, + { + "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": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2alpha_generated_model_service_create_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_CreateModel_async", + "segments": [ + { + "end": 64, + "start": 27, + "type": "FULL" + }, + { + "end": 64, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 54, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 61, + "start": 55, + "type": "REQUEST_EXECUTION" + }, + { + "end": 65, + "start": 62, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_model_service_create_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2alpha.types.Model" + }, + { + "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": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2alpha_generated_model_service_create_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_CreateModel_sync", + "segments": [ + { + "end": 64, + "start": 27, + "type": "FULL" + }, + { + "end": 64, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 54, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 61, + "start": 55, + "type": "REQUEST_EXECUTION" + }, + { + "end": 65, + "start": 62, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_model_service_create_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteModelRequest" + }, + { + "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_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2alpha_generated_model_service_delete_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_DeleteModel_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": "retail_v2alpha_generated_model_service_delete_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteModelRequest" + }, + { + "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_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2alpha_generated_model_service_delete_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_DeleteModel_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": "retail_v2alpha_generated_model_service_delete_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetModelRequest" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2alpha_generated_model_service_get_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_GetModel_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": "retail_v2alpha_generated_model_service_get_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetModelRequest" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2alpha_generated_model_service_get_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_GetModel_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": "retail_v2alpha_generated_model_service_get_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListModelsRequest" + }, + { + "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.retail_v2alpha.services.model_service.pagers.ListModelsAsyncPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2alpha_generated_model_service_list_models_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_ListModels_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": "retail_v2alpha_generated_model_service_list_models_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListModelsRequest" + }, + { + "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.retail_v2alpha.services.model_service.pagers.ListModelsPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2alpha_generated_model_service_list_models_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_ListModels_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": "retail_v2alpha_generated_model_service_list_models_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PauseModelRequest" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2alpha_generated_model_service_pause_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_PauseModel_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": "retail_v2alpha_generated_model_service_pause_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PauseModelRequest" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2alpha_generated_model_service_pause_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_PauseModel_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": "retail_v2alpha_generated_model_service_pause_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ResumeModelRequest" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2alpha_generated_model_service_resume_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_ResumeModel_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": "retail_v2alpha_generated_model_service_resume_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ResumeModelRequest" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2alpha_generated_model_service_resume_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_ResumeModel_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": "retail_v2alpha_generated_model_service_resume_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.TuneModelRequest" + }, + { + "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.api_core.operation_async.AsyncOperation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2alpha_generated_model_service_tune_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_TuneModel_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": "retail_v2alpha_generated_model_service_tune_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.TuneModelRequest" + }, + { + "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.api_core.operation.Operation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2alpha_generated_model_service_tune_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_TuneModel_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": "retail_v2alpha_generated_model_service_tune_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceAsyncClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2alpha.types.Model" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2alpha_generated_model_service_update_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_UpdateModel_async", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 53, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 54, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_model_service_update_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ModelServiceClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2alpha.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2alpha.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2alpha.types.Model" + }, + { + "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.retail_v2alpha.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2alpha_generated_model_service_update_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ModelService_UpdateModel_sync", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 53, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 54, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_model_service_update_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.PredictionServiceAsyncClient", + "shortName": "PredictionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.PredictionServiceAsyncClient.predict", + "method": { + "fullName": "google.cloud.retail.v2alpha.PredictionService.Predict", + "service": { + "fullName": "google.cloud.retail.v2alpha.PredictionService", + "shortName": "PredictionService" + }, + "shortName": "Predict" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PredictRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.PredictResponse", + "shortName": "predict" + }, + "description": "Sample for Predict", + "file": "retail_v2alpha_generated_prediction_service_predict_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_PredictionService_Predict_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_prediction_service_predict_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.PredictionServiceClient", + "shortName": "PredictionServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.PredictionServiceClient.predict", + "method": { + "fullName": "google.cloud.retail.v2alpha.PredictionService.Predict", + "service": { + "fullName": "google.cloud.retail.v2alpha.PredictionService", + "shortName": "PredictionService" + }, + "shortName": "Predict" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PredictRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.PredictResponse", + "shortName": "predict" + }, + "description": "Sample for Predict", + "file": "retail_v2alpha_generated_prediction_service_predict_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_PredictionService_Predict_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_prediction_service_predict_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.add_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "add_fulfillment_places" + }, + "description": "Sample for AddFulfillmentPlaces", + "file": "retail_v2alpha_generated_product_service_add_fulfillment_places_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_AddFulfillmentPlaces_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_add_fulfillment_places_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.add_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.AddFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "add_fulfillment_places" + }, + "description": "Sample for AddFulfillmentPlaces", + "file": "retail_v2alpha_generated_product_service_add_fulfillment_places_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_AddFulfillmentPlaces_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_add_fulfillment_places_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.add_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.AddLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddLocalInventoriesRequest" + }, + { + "name": "product", + "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": "add_local_inventories" + }, + "description": "Sample for AddLocalInventories", + "file": "retail_v2alpha_generated_product_service_add_local_inventories_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_AddLocalInventories_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": "retail_v2alpha_generated_product_service_add_local_inventories_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.add_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.AddLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddLocalInventoriesRequest" + }, + { + "name": "product", + "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": "add_local_inventories" + }, + "description": "Sample for AddLocalInventories", + "file": "retail_v2alpha_generated_product_service_add_local_inventories_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_AddLocalInventories_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": "retail_v2alpha_generated_product_service_add_local_inventories_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.create_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.CreateProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "retail_v2alpha_generated_product_service_create_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_CreateProduct_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_create_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.create_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.CreateProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "retail_v2alpha_generated_product_service_create_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_CreateProduct_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_create_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.delete_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.DeleteProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.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": "retail_v2alpha_generated_product_service_delete_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_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": "retail_v2alpha_generated_product_service_delete_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.delete_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.DeleteProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.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": "retail_v2alpha_generated_product_service_delete_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_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": "retail_v2alpha_generated_product_service_delete_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.get_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.GetProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "retail_v2alpha_generated_product_service_get_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_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": "retail_v2alpha_generated_product_service_get_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.get_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.GetProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "retail_v2alpha_generated_product_service_get_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_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": "retail_v2alpha_generated_product_service_get_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.import_products", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.ImportProducts", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "ImportProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ImportProductsRequest" + }, + { + "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_products" + }, + "description": "Sample for ImportProducts", + "file": "retail_v2alpha_generated_product_service_import_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_ImportProducts_async", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_import_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.import_products", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.ImportProducts", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "ImportProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ImportProductsRequest" + }, + { + "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_products" + }, + "description": "Sample for ImportProducts", + "file": "retail_v2alpha_generated_product_service_import_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_ImportProducts_sync", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_import_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.list_products", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.ListProducts", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.services.product_service.pagers.ListProductsAsyncPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "retail_v2alpha_generated_product_service_list_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_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": "retail_v2alpha_generated_product_service_list_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.list_products", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.ListProducts", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.services.product_service.pagers.ListProductsPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "retail_v2alpha_generated_product_service_list_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_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": "retail_v2alpha_generated_product_service_list_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.purge_products", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.PurgeProducts", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "PurgeProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PurgeProductsRequest" + }, + { + "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": "retail_v2alpha_generated_product_service_purge_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_PurgeProducts_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_purge_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.purge_products", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.PurgeProducts", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "PurgeProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PurgeProductsRequest" + }, + { + "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": "retail_v2alpha_generated_product_service_purge_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_PurgeProducts_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_purge_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.remove_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "remove_fulfillment_places" + }, + "description": "Sample for RemoveFulfillmentPlaces", + "file": "retail_v2alpha_generated_product_service_remove_fulfillment_places_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_RemoveFulfillmentPlaces_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_remove_fulfillment_places_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.remove_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.RemoveFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "remove_fulfillment_places" + }, + "description": "Sample for RemoveFulfillmentPlaces", + "file": "retail_v2alpha_generated_product_service_remove_fulfillment_places_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_RemoveFulfillmentPlaces_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_remove_fulfillment_places_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.remove_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveLocalInventoriesRequest" + }, + { + "name": "product", + "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": "remove_local_inventories" + }, + "description": "Sample for RemoveLocalInventories", + "file": "retail_v2alpha_generated_product_service_remove_local_inventories_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_RemoveLocalInventories_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_remove_local_inventories_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.remove_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.RemoveLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveLocalInventoriesRequest" + }, + { + "name": "product", + "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": "remove_local_inventories" + }, + "description": "Sample for RemoveLocalInventories", + "file": "retail_v2alpha_generated_product_service_remove_local_inventories_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_RemoveLocalInventories_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_remove_local_inventories_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.set_inventory", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.SetInventory", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "SetInventory" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.SetInventoryRequest" + }, + { + "name": "inventory", + "type": "google.cloud.retail_v2alpha.types.Product" + }, + { + "name": "set_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.api_core.operation_async.AsyncOperation", + "shortName": "set_inventory" + }, + "description": "Sample for SetInventory", + "file": "retail_v2alpha_generated_product_service_set_inventory_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_SetInventory_async", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_set_inventory_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.set_inventory", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.SetInventory", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "SetInventory" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.SetInventoryRequest" + }, + { + "name": "inventory", + "type": "google.cloud.retail_v2alpha.types.Product" + }, + { + "name": "set_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.api_core.operation.Operation", + "shortName": "set_inventory" + }, + "description": "Sample for SetInventory", + "file": "retail_v2alpha_generated_product_service_set_inventory_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_SetInventory_sync", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_set_inventory_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceAsyncClient.update_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.UpdateProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "retail_v2alpha_generated_product_service_update_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_UpdateProduct_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_update_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ProductServiceClient.update_product", + "method": { + "fullName": "google.cloud.retail.v2alpha.ProductService.UpdateProduct", + "service": { + "fullName": "google.cloud.retail.v2alpha.ProductService", + "shortName": "ProductService" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.retail_v2alpha.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.retail_v2alpha.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "retail_v2alpha_generated_product_service_update_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ProductService_UpdateProduct_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_product_service_update_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.SearchServiceAsyncClient", + "shortName": "SearchServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.SearchServiceAsyncClient.search", + "method": { + "fullName": "google.cloud.retail.v2alpha.SearchService.Search", + "service": { + "fullName": "google.cloud.retail.v2alpha.SearchService", + "shortName": "SearchService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.SearchRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.services.search_service.pagers.SearchAsyncPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "retail_v2alpha_generated_search_service_search_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_SearchService_Search_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_search_service_search_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.SearchServiceClient", + "shortName": "SearchServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.SearchServiceClient.search", + "method": { + "fullName": "google.cloud.retail.v2alpha.SearchService.Search", + "service": { + "fullName": "google.cloud.retail.v2alpha.SearchService", + "shortName": "SearchService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.SearchRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.services.search_service.pagers.SearchPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "retail_v2alpha_generated_search_service_search_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_SearchService_Search_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_search_service_search_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient.add_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.AddControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "AddControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.ServingConfig", + "shortName": "add_control" + }, + "description": "Sample for AddControl", + "file": "retail_v2alpha_generated_serving_config_service_add_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_AddControl_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_serving_config_service_add_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient.add_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.AddControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "AddControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.AddControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.ServingConfig", + "shortName": "add_control" + }, + "description": "Sample for AddControl", + "file": "retail_v2alpha_generated_serving_config_service_add_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_AddControl_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_serving_config_service_add_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient.create_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.CreateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "CreateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateServingConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2alpha.types.ServingConfig" + }, + { + "name": "serving_config_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.retail_v2alpha.types.ServingConfig", + "shortName": "create_serving_config" + }, + "description": "Sample for CreateServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_create_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_CreateServingConfig_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_serving_config_service_create_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient.create_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.CreateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "CreateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CreateServingConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2alpha.types.ServingConfig" + }, + { + "name": "serving_config_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.retail_v2alpha.types.ServingConfig", + "shortName": "create_serving_config" + }, + "description": "Sample for CreateServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_create_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_CreateServingConfig_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_serving_config_service_create_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient.delete_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.DeleteServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "DeleteServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteServingConfigRequest" + }, + { + "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_serving_config" + }, + "description": "Sample for DeleteServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_delete_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_DeleteServingConfig_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": "retail_v2alpha_generated_serving_config_service_delete_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient.delete_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.DeleteServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "DeleteServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.DeleteServingConfigRequest" + }, + { + "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_serving_config" + }, + "description": "Sample for DeleteServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_delete_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_DeleteServingConfig_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": "retail_v2alpha_generated_serving_config_service_delete_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient.get_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.GetServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "GetServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetServingConfigRequest" + }, + { + "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.retail_v2alpha.types.ServingConfig", + "shortName": "get_serving_config" + }, + "description": "Sample for GetServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_get_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_GetServingConfig_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": "retail_v2alpha_generated_serving_config_service_get_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient.get_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.GetServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "GetServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.GetServingConfigRequest" + }, + { + "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.retail_v2alpha.types.ServingConfig", + "shortName": "get_serving_config" + }, + "description": "Sample for GetServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_get_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_GetServingConfig_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": "retail_v2alpha_generated_serving_config_service_get_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient.list_serving_configs", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.ListServingConfigs", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "ListServingConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListServingConfigsRequest" + }, + { + "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.retail_v2alpha.services.serving_config_service.pagers.ListServingConfigsAsyncPager", + "shortName": "list_serving_configs" + }, + "description": "Sample for ListServingConfigs", + "file": "retail_v2alpha_generated_serving_config_service_list_serving_configs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_ListServingConfigs_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": "retail_v2alpha_generated_serving_config_service_list_serving_configs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient.list_serving_configs", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.ListServingConfigs", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "ListServingConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ListServingConfigsRequest" + }, + { + "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.retail_v2alpha.services.serving_config_service.pagers.ListServingConfigsPager", + "shortName": "list_serving_configs" + }, + "description": "Sample for ListServingConfigs", + "file": "retail_v2alpha_generated_serving_config_service_list_serving_configs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_ListServingConfigs_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": "retail_v2alpha_generated_serving_config_service_list_serving_configs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient.remove_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.RemoveControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "RemoveControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.ServingConfig", + "shortName": "remove_control" + }, + "description": "Sample for RemoveControl", + "file": "retail_v2alpha_generated_serving_config_service_remove_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_RemoveControl_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_serving_config_service_remove_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient.remove_control", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.RemoveControl", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "RemoveControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RemoveControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.ServingConfig", + "shortName": "remove_control" + }, + "description": "Sample for RemoveControl", + "file": "retail_v2alpha_generated_serving_config_service_remove_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_RemoveControl_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_serving_config_service_remove_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceAsyncClient.update_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.UpdateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "UpdateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateServingConfigRequest" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2alpha.types.ServingConfig" + }, + { + "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.retail_v2alpha.types.ServingConfig", + "shortName": "update_serving_config" + }, + "description": "Sample for UpdateServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_update_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_UpdateServingConfig_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": "retail_v2alpha_generated_serving_config_service_update_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.ServingConfigServiceClient.update_serving_config", + "method": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService.UpdateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2alpha.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "UpdateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.UpdateServingConfigRequest" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2alpha.types.ServingConfig" + }, + { + "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.retail_v2alpha.types.ServingConfig", + "shortName": "update_serving_config" + }, + "description": "Sample for UpdateServingConfig", + "file": "retail_v2alpha_generated_serving_config_service_update_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_ServingConfigService_UpdateServingConfig_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": "retail_v2alpha_generated_serving_config_service_update_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient.collect_user_event", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.CollectUserEvent", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "CollectUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CollectUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api.httpbody_pb2.HttpBody", + "shortName": "collect_user_event" + }, + "description": "Sample for CollectUserEvent", + "file": "retail_v2alpha_generated_user_event_service_collect_user_event_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_CollectUserEvent_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_collect_user_event_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient.collect_user_event", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.CollectUserEvent", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "CollectUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.CollectUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api.httpbody_pb2.HttpBody", + "shortName": "collect_user_event" + }, + "description": "Sample for CollectUserEvent", + "file": "retail_v2alpha_generated_user_event_service_collect_user_event_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_CollectUserEvent_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_collect_user_event_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient.import_user_events", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.ImportUserEvents", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "ImportUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ImportUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for ImportUserEvents", + "file": "retail_v2alpha_generated_user_event_service_import_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_ImportUserEvents_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_import_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient.import_user_events", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.ImportUserEvents", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "ImportUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.ImportUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for ImportUserEvents", + "file": "retail_v2alpha_generated_user_event_service_import_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_ImportUserEvents_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_import_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient.purge_user_events", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.PurgeUserEvents", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "PurgeUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PurgeUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for PurgeUserEvents", + "file": "retail_v2alpha_generated_user_event_service_purge_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_PurgeUserEvents_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_purge_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient.purge_user_events", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.PurgeUserEvents", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "PurgeUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.PurgeUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for PurgeUserEvents", + "file": "retail_v2alpha_generated_user_event_service_purge_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_PurgeUserEvents_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_purge_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient.rejoin_user_events", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.RejoinUserEvents", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "RejoinUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RejoinUserEventsRequest" + }, + { + "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": "rejoin_user_events" + }, + "description": "Sample for RejoinUserEvents", + "file": "retail_v2alpha_generated_user_event_service_rejoin_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_RejoinUserEvents_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": "retail_v2alpha_generated_user_event_service_rejoin_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient.rejoin_user_events", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.RejoinUserEvents", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "RejoinUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.RejoinUserEventsRequest" + }, + { + "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": "rejoin_user_events" + }, + "description": "Sample for RejoinUserEvents", + "file": "retail_v2alpha_generated_user_event_service_rejoin_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_RejoinUserEvents_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": "retail_v2alpha_generated_user_event_service_rejoin_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceAsyncClient.write_user_event", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.WriteUserEvent", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "WriteUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.WriteUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.UserEvent", + "shortName": "write_user_event" + }, + "description": "Sample for WriteUserEvent", + "file": "retail_v2alpha_generated_user_event_service_write_user_event_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_WriteUserEvent_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_write_user_event_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2alpha.UserEventServiceClient.write_user_event", + "method": { + "fullName": "google.cloud.retail.v2alpha.UserEventService.WriteUserEvent", + "service": { + "fullName": "google.cloud.retail.v2alpha.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "WriteUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2alpha.types.WriteUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2alpha.types.UserEvent", + "shortName": "write_user_event" + }, + "description": "Sample for WriteUserEvent", + "file": "retail_v2alpha_generated_user_event_service_write_user_event_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2alpha_generated_UserEventService_WriteUserEvent_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2alpha_generated_user_event_service_write_user_event_sync.py" + } + ] +} diff --git a/owl-bot-staging/v2alpha/scripts/fixup_retail_v2alpha_keywords.py b/owl-bot-staging/v2alpha/scripts/fixup_retail_v2alpha_keywords.py new file mode 100644 index 00000000..5d23fabb --- /dev/null +++ b/owl-bot-staging/v2alpha/scripts/fixup_retail_v2alpha_keywords.py @@ -0,0 +1,231 @@ +#! /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 retailCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'add_catalog_attribute': ('attributes_config', 'catalog_attribute', ), + 'add_control': ('serving_config', 'control_id', ), + 'add_fulfillment_places': ('product', 'type_', 'place_ids', 'add_time', 'allow_missing', ), + 'add_local_inventories': ('product', 'local_inventories', 'add_mask', 'add_time', 'allow_missing', ), + 'batch_remove_catalog_attributes': ('attributes_config', 'attribute_keys', ), + 'collect_user_event': ('parent', 'user_event', 'prebuilt_rule', 'uri', 'ets', 'raw_json', ), + 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', 'enable_attribute_suggestions', 'entity', ), + 'create_control': ('parent', 'control', 'control_id', ), + 'create_merchant_center_account_link': ('parent', 'merchant_center_account_link', ), + 'create_model': ('parent', 'model', 'dry_run', ), + 'create_product': ('parent', 'product', 'product_id', ), + 'create_serving_config': ('parent', 'serving_config', 'serving_config_id', ), + 'delete_control': ('name', ), + 'delete_merchant_center_account_link': ('name', ), + 'delete_model': ('name', ), + 'delete_product': ('name', 'force', ), + 'delete_serving_config': ('name', ), + 'get_attributes_config': ('name', ), + 'get_completion_config': ('name', ), + 'get_control': ('name', ), + 'get_default_branch': ('catalog', ), + 'get_model': ('name', ), + 'get_product': ('name', ), + 'get_serving_config': ('name', ), + 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), + 'import_products': ('parent', 'input_config', 'request_id', 'errors_config', 'update_mask', 'reconciliation_mode', 'notification_pubsub_topic', 'skip_default_branch_protection', ), + 'import_user_events': ('parent', 'input_config', 'errors_config', ), + 'list_catalogs': ('parent', 'page_size', 'page_token', ), + 'list_controls': ('parent', 'page_size', 'page_token', 'filter', ), + 'list_merchant_center_account_links': ('parent', ), + 'list_models': ('parent', 'page_size', 'page_token', ), + 'list_products': ('parent', 'page_size', 'page_token', 'filter', 'read_mask', 'require_total_size', ), + 'list_serving_configs': ('parent', 'page_size', 'page_token', ), + 'pause_model': ('name', ), + 'predict': ('placement', 'user_event', 'page_size', 'page_token', 'filter', 'validate_only', 'params', 'labels', ), + 'purge_products': ('parent', 'filter', 'force', ), + 'purge_user_events': ('parent', 'filter', 'force', ), + 'rejoin_user_events': ('parent', 'user_event_rejoin_scope', ), + 'remove_catalog_attribute': ('attributes_config', 'key', ), + 'remove_control': ('serving_config', 'control_id', ), + 'remove_fulfillment_places': ('product', 'type_', 'place_ids', 'remove_time', 'allow_missing', ), + 'remove_local_inventories': ('product', 'place_ids', 'remove_time', 'allow_missing', ), + 'replace_catalog_attribute': ('attributes_config', 'catalog_attribute', 'update_mask', ), + 'resume_model': ('name', ), + 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'relevance_threshold', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', 'entity', ), + 'set_default_branch': ('catalog', 'branch_id', 'note', 'force', ), + 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), + 'tune_model': ('name', ), + 'update_attributes_config': ('attributes_config', 'update_mask', ), + 'update_catalog': ('catalog', 'update_mask', ), + 'update_completion_config': ('completion_config', 'update_mask', ), + 'update_control': ('control', 'update_mask', ), + 'update_model': ('model', 'update_mask', ), + 'update_product': ('product', 'update_mask', 'allow_missing', ), + 'update_serving_config': ('serving_config', 'update_mask', ), + 'write_user_event': ('parent', 'user_event', 'write_async', ), + } + + 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=retailCallTransformer(), +): + """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 retail 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/v2alpha/setup.py b/owl-bot-staging/v2alpha/setup.py new file mode 100644 index 00000000..458c0728 --- /dev/null +++ b/owl-bot-staging/v2alpha/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-retail' + + +description = "Google Cloud Retail API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/retail/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-retail" + +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/v2alpha/testing/constraints-3.10.txt b/owl-bot-staging/v2alpha/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/testing/constraints-3.11.txt b/owl-bot-staging/v2alpha/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/testing/constraints-3.12.txt b/owl-bot-staging/v2alpha/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/testing/constraints-3.7.txt b/owl-bot-staging/v2alpha/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/testing/constraints-3.8.txt b/owl-bot-staging/v2alpha/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/testing/constraints-3.9.txt b/owl-bot-staging/v2alpha/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/tests/__init__.py b/owl-bot-staging/v2alpha/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/tests/unit/__init__.py b/owl-bot-staging/v2alpha/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/tests/unit/gapic/__init__.py b/owl-bot-staging/v2alpha/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2alpha/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/v2alpha/tests/unit/gapic/retail_v2alpha/__init__.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/__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/v2alpha/tests/unit/gapic/retail_v2alpha/test_catalog_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_catalog_service.py new file mode 100644 index 00000000..8b4a59f3 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_catalog_service.py @@ -0,0 +1,6992 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.catalog_service import CatalogServiceAsyncClient +from google.cloud.retail_v2alpha.services.catalog_service import CatalogServiceClient +from google.cloud.retail_v2alpha.services.catalog_service import pagers +from google.cloud.retail_v2alpha.services.catalog_service import transports +from google.cloud.retail_v2alpha.types import catalog +from google.cloud.retail_v2alpha.types import catalog as gcr_catalog +from google.cloud.retail_v2alpha.types import catalog_service +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.type import date_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 CatalogServiceClient._get_default_mtls_endpoint(None) is None + assert CatalogServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (CatalogServiceClient, "grpc"), + (CatalogServiceAsyncClient, "grpc_asyncio"), + (CatalogServiceClient, "rest"), +]) +def test_catalog_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CatalogServiceGrpcTransport, "grpc"), + (transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.CatalogServiceRestTransport, "rest"), +]) +def test_catalog_service_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", [ + (CatalogServiceClient, "grpc"), + (CatalogServiceAsyncClient, "grpc_asyncio"), + (CatalogServiceClient, "rest"), +]) +def test_catalog_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_catalog_service_client_get_transport_class(): + transport = CatalogServiceClient.get_transport_class() + available_transports = [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceRestTransport, + ] + assert transport in available_transports + + transport = CatalogServiceClient.get_transport_class("grpc") + assert transport == transports.CatalogServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_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(CatalogServiceClient, '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(CatalogServiceClient, '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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "true"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "false"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", "true"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_catalog_service_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", [ + CatalogServiceClient, CatalogServiceAsyncClient +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest"), +]) +def test_catalog_service_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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", grpc_helpers), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", None), +]) +def test_catalog_service_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_catalog_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.catalog_service.transports.CatalogServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CatalogServiceClient( + 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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", grpc_helpers), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_catalog_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ListCatalogsRequest, + dict, +]) +def test_list_catalogs(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_catalogs_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 = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + client.list_catalogs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + +@pytest.mark.asyncio +async def test_list_catalogs_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ListCatalogsRequest): + client = CatalogServiceAsyncClient( + 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_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_catalogs_async_from_dict(): + await test_list_catalogs_async(request_type=dict) + + +def test_list_catalogs_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = catalog_service.ListCatalogsResponse() + client.list_catalogs(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_catalogs_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.ListCatalogsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + await client.list_catalogs(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_catalogs_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_catalogs( + 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_catalogs_flattened_error(): + client = CatalogServiceClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_catalogs_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_catalogs( + 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_catalogs_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + + +def test_list_catalogs_pager(transport_name: str = "grpc"): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_catalogs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in results) +def test_list_catalogs_pages(transport_name: str = "grpc"): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + pages = list(client.list_catalogs(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_catalogs_async_pager(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_catalogs(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, catalog.Catalog) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_catalogs_async_pages(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + 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_catalogs(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", [ + catalog_service.UpdateCatalogRequest, + dict, +]) +def test_update_catalog(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + ) + response = client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_catalog_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 = CatalogServiceClient( + 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_catalog), + '__call__') as call: + client.update_catalog() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + +@pytest.mark.asyncio +async def test_update_catalog_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCatalogRequest): + client = CatalogServiceAsyncClient( + 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_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + )) + response = await client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_update_catalog_async_from_dict(): + await test_update_catalog_async(request_type=dict) + + +def test_update_catalog_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = gcr_catalog.Catalog() + client.update_catalog(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', + 'catalog.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_catalog_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + await client.update_catalog(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', + 'catalog.name=name_value', + ) in kw['metadata'] + + +def test_update_catalog_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_catalog( + catalog=gcr_catalog.Catalog(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].catalog + mock_val = gcr_catalog.Catalog(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_catalog_flattened_error(): + client = CatalogServiceClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_catalog_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_catalog( + catalog=gcr_catalog.Catalog(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].catalog + mock_val = gcr_catalog.Catalog(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_catalog_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.SetDefaultBranchRequest, + dict, +]) +def test_set_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_set_default_branch_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 = CatalogServiceClient( + 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.set_default_branch), + '__call__') as call: + client.set_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + +@pytest.mark.asyncio +async def test_set_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.SetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + 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.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_set_default_branch_async_from_dict(): + await test_set_default_branch_async(request_type=dict) + + +def test_set_default_branch_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = None + client.set_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.set_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +def test_set_default_branch_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__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.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_set_default_branch_flattened_error(): + client = CatalogServiceClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__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.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetDefaultBranchRequest, + dict, +]) +def test_get_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + ) + response = client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +def test_get_default_branch_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 = CatalogServiceClient( + 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_default_branch), + '__call__') as call: + client.get_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + +@pytest.mark.asyncio +async def test_get_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + 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_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + )) + response = await client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +@pytest.mark.asyncio +async def test_get_default_branch_async_from_dict(): + await test_get_default_branch_async(request_type=dict) + + +def test_get_default_branch_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = catalog_service.GetDefaultBranchResponse() + client.get_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + await client.get_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +def test_get_default_branch_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_get_default_branch_flattened_error(): + client = CatalogServiceClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetCompletionConfigRequest, + dict, +]) +def test_get_completion_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + response = client.get_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_get_completion_config_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 = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + client.get_completion_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + +@pytest.mark.asyncio +async def test_get_completion_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetCompletionConfigRequest): + client = CatalogServiceAsyncClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + )) + response = await client.get_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +@pytest.mark.asyncio +async def test_get_completion_config_async_from_dict(): + await test_get_completion_config_async(request_type=dict) + + +def test_get_completion_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetCompletionConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + call.return_value = catalog.CompletionConfig() + client.get_completion_config(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_completion_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetCompletionConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + await client.get_completion_config(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_completion_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_completion_config( + 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_completion_config_flattened_error(): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_completion_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_completion_config( + 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_completion_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateCompletionConfigRequest, + dict, +]) +def test_update_completion_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + response = client.update_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_update_completion_config_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 = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + client.update_completion_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + +@pytest.mark.asyncio +async def test_update_completion_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCompletionConfigRequest): + client = CatalogServiceAsyncClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + )) + response = await client.update_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +@pytest.mark.asyncio +async def test_update_completion_config_async_from_dict(): + await test_update_completion_config_async(request_type=dict) + + +def test_update_completion_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateCompletionConfigRequest() + + request.completion_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + call.return_value = catalog.CompletionConfig() + client.update_completion_config(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', + 'completion_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_completion_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateCompletionConfigRequest() + + request.completion_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + await client.update_completion_config(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', + 'completion_config.name=name_value', + ) in kw['metadata'] + + +def test_update_completion_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_completion_config( + completion_config=catalog.CompletionConfig(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].completion_config + mock_val = catalog.CompletionConfig(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_completion_config_flattened_error(): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_completion_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_completion_config( + completion_config=catalog.CompletionConfig(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].completion_config + mock_val = catalog.CompletionConfig(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_completion_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetAttributesConfigRequest, + dict, +]) +def test_get_attributes_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.get_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_get_attributes_config_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 = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + client.get_attributes_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + +@pytest.mark.asyncio +async def test_get_attributes_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetAttributesConfigRequest): + client = CatalogServiceAsyncClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.get_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_get_attributes_config_async_from_dict(): + await test_get_attributes_config_async(request_type=dict) + + +def test_get_attributes_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetAttributesConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.get_attributes_config(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_attributes_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetAttributesConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.get_attributes_config(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_attributes_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_attributes_config( + 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_attributes_config_flattened_error(): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_attributes_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_attributes_config( + 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_attributes_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateAttributesConfigRequest, + dict, +]) +def test_update_attributes_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.update_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_update_attributes_config_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 = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + client.update_attributes_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + +@pytest.mark.asyncio +async def test_update_attributes_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateAttributesConfigRequest): + client = CatalogServiceAsyncClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.update_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_update_attributes_config_async_from_dict(): + await test_update_attributes_config_async(request_type=dict) + + +def test_update_attributes_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateAttributesConfigRequest() + + request.attributes_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.update_attributes_config(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', + 'attributes_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_attributes_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateAttributesConfigRequest() + + request.attributes_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.update_attributes_config(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', + 'attributes_config.name=name_value', + ) in kw['metadata'] + + +def test_update_attributes_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_attributes_config( + attributes_config=catalog.AttributesConfig(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].attributes_config + mock_val = catalog.AttributesConfig(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_attributes_config_flattened_error(): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_attributes_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_attributes_config( + attributes_config=catalog.AttributesConfig(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].attributes_config + mock_val = catalog.AttributesConfig(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_attributes_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.AddCatalogAttributeRequest, + dict, +]) +def test_add_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.add_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_add_catalog_attribute_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 = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + client.add_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_add_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.AddCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.add_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_add_catalog_attribute_async_from_dict(): + await test_add_catalog_attribute_async(request_type=dict) + + +def test_add_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.AddCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.add_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.AddCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.add_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.RemoveCatalogAttributeRequest, + dict, +]) +def test_remove_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.remove_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_remove_catalog_attribute_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 = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + client.remove_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.RemoveCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.remove_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_async_from_dict(): + await test_remove_catalog_attribute_async(request_type=dict) + + +def test_remove_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.RemoveCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.remove_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.RemoveCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.remove_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.BatchRemoveCatalogAttributesRequest, + dict, +]) +def test_batch_remove_catalog_attributes(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_remove_catalog_attributes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=['deleted_catalog_attributes_value'], + reset_catalog_attributes=['reset_catalog_attributes_value'], + ) + response = client.batch_remove_catalog_attributes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ['deleted_catalog_attributes_value'] + assert response.reset_catalog_attributes == ['reset_catalog_attributes_value'] + + +def test_batch_remove_catalog_attributes_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 = CatalogServiceClient( + 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_remove_catalog_attributes), + '__call__') as call: + client.batch_remove_catalog_attributes() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_async(transport: str = 'grpc_asyncio', request_type=catalog_service.BatchRemoveCatalogAttributesRequest): + client = CatalogServiceAsyncClient( + 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_remove_catalog_attributes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=['deleted_catalog_attributes_value'], + reset_catalog_attributes=['reset_catalog_attributes_value'], + )) + response = await client.batch_remove_catalog_attributes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ['deleted_catalog_attributes_value'] + assert response.reset_catalog_attributes == ['reset_catalog_attributes_value'] + + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_async_from_dict(): + await test_batch_remove_catalog_attributes_async(request_type=dict) + + +def test_batch_remove_catalog_attributes_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.BatchRemoveCatalogAttributesRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_remove_catalog_attributes), + '__call__') as call: + call.return_value = catalog_service.BatchRemoveCatalogAttributesResponse() + client.batch_remove_catalog_attributes(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.BatchRemoveCatalogAttributesRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_remove_catalog_attributes), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.BatchRemoveCatalogAttributesResponse()) + await client.batch_remove_catalog_attributes(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ReplaceCatalogAttributeRequest, + dict, +]) +def test_replace_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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.replace_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.replace_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_replace_catalog_attribute_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 = CatalogServiceClient( + 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.replace_catalog_attribute), + '__call__') as call: + client.replace_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ReplaceCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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.replace_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.replace_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_async_from_dict(): + await test_replace_catalog_attribute_async(request_type=dict) + + +def test_replace_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.ReplaceCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.replace_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.replace_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.ReplaceCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.replace_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.replace_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ListCatalogsRequest, + dict, +]) +def test_list_catalogs_rest(request_type): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_catalogs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_catalogs_rest_required_fields(request_type=catalog_service.ListCatalogsRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_catalogs._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_catalogs._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog_service.ListCatalogsResponse() + # 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 + + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_catalogs(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_catalogs_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_catalogs._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_catalogs_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_list_catalogs") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_list_catalogs") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.ListCatalogsRequest.pb(catalog_service.ListCatalogsRequest()) + 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 = catalog_service.ListCatalogsResponse.to_json(catalog_service.ListCatalogsResponse()) + + request = catalog_service.ListCatalogsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.ListCatalogsResponse() + + client.list_catalogs(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_catalogs_rest_bad_request(transport: str = 'rest', request_type=catalog_service.ListCatalogsRequest): + client = CatalogServiceClient( + 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_catalogs(request) + + +def test_list_catalogs_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsResponse() + + # 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 + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_catalogs(**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/v2alpha/{parent=projects/*/locations/*}/catalogs" % client.transport._host, args[1]) + + +def test_list_catalogs_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + + +def test_list_catalogs_rest_pager(transport: str = 'rest'): + client = CatalogServiceClient( + 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 = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(catalog_service.ListCatalogsResponse.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_catalogs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in results) + + pages = list(client.list_catalogs(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", [ + catalog_service.UpdateCatalogRequest, + dict, +]) +def test_update_catalog_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + request_init["catalog"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3', 'display_name': 'display_name_value', 'product_level_config': {'ingestion_product_type': 'ingestion_product_type_value', 'merchant_center_product_id_field': 'merchant_center_product_id_field_value'}, 'merchant_center_linking_config': {'links': [{'merchant_center_account_id': 2730, 'branch_id': 'branch_id_value', 'destinations': ['destinations_value1', 'destinations_value2'], 'region_code': 'region_code_value', 'language_code': 'language_code_value', 'feeds': [{'primary_feed_id': 1571, 'primary_feed_name': 'primary_feed_name_value'}]}]}} + 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 = gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_catalog(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_catalog_rest_required_fields(request_type=catalog_service.UpdateCatalogRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_catalog._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_catalog._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_catalog.Catalog() + # 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 + + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_catalog(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_catalog_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_catalog._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("catalog", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_catalog_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_catalog") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_catalog") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateCatalogRequest.pb(catalog_service.UpdateCatalogRequest()) + 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 = gcr_catalog.Catalog.to_json(gcr_catalog.Catalog()) + + request = catalog_service.UpdateCatalogRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_catalog.Catalog() + + client.update_catalog(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_catalog_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateCatalogRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + request_init["catalog"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3', 'display_name': 'display_name_value', 'product_level_config': {'ingestion_product_type': 'ingestion_product_type_value', 'merchant_center_product_id_field': 'merchant_center_product_id_field_value'}, 'merchant_center_linking_config': {'links': [{'merchant_center_account_id': 2730, 'branch_id': 'branch_id_value', 'destinations': ['destinations_value1', 'destinations_value2'], 'region_code': 'region_code_value', 'language_code': 'language_code_value', 'feeds': [{'primary_feed_id': 1571, 'primary_feed_name': 'primary_feed_name_value'}]}]}} + 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_catalog(request) + + +def test_update_catalog_rest_flattened(): + client = CatalogServiceClient( + 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 = gcr_catalog.Catalog() + + # get arguments that satisfy an http rule for this method + sample_request = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + catalog=gcr_catalog.Catalog(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 + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_catalog(**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/v2alpha/{catalog.name=projects/*/locations/*/catalogs/*}" % client.transport._host, args[1]) + + +def test_update_catalog_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_catalog_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.SetDefaultBranchRequest, + dict, +]) +def test_set_default_branch_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.set_default_branch(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_default_branch_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "pre_set_default_branch") as pre: + pre.assert_not_called() + pb_message = catalog_service.SetDefaultBranchRequest.pb(catalog_service.SetDefaultBranchRequest()) + 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 = catalog_service.SetDefaultBranchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.set_default_branch(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_set_default_branch_rest_bad_request(transport: str = 'rest', request_type=catalog_service.SetDefaultBranchRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.set_default_branch(request) + + +def test_set_default_branch_rest_flattened(): + client = CatalogServiceClient( + 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 = {'catalog': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + catalog='catalog_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.set_default_branch(**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/v2alpha/{catalog=projects/*/locations/*/catalogs/*}:setDefaultBranch" % client.transport._host, args[1]) + + +def test_set_default_branch_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +def test_set_default_branch_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetDefaultBranchRequest, + dict, +]) +def test_get_default_branch_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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 = catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.GetDefaultBranchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_default_branch(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_default_branch_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_default_branch") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_default_branch") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetDefaultBranchRequest.pb(catalog_service.GetDefaultBranchRequest()) + 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 = catalog_service.GetDefaultBranchResponse.to_json(catalog_service.GetDefaultBranchResponse()) + + request = catalog_service.GetDefaultBranchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.GetDefaultBranchResponse() + + client.get_default_branch(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_default_branch_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetDefaultBranchRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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_default_branch(request) + + +def test_get_default_branch_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog_service.GetDefaultBranchResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'catalog': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + catalog='catalog_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.GetDefaultBranchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_default_branch(**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/v2alpha/{catalog=projects/*/locations/*/catalogs/*}:getDefaultBranch" % client.transport._host, args[1]) + + +def test_get_default_branch_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +def test_get_default_branch_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetCompletionConfigRequest, + dict, +]) +def test_get_completion_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + 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 = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_completion_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_get_completion_config_rest_required_fields(request_type=catalog_service.GetCompletionConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_completion_config._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_completion_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.CompletionConfig() + # 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 + + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_completion_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_completion_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_completion_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_completion_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_completion_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_completion_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetCompletionConfigRequest.pb(catalog_service.GetCompletionConfigRequest()) + 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 = catalog.CompletionConfig.to_json(catalog.CompletionConfig()) + + request = catalog_service.GetCompletionConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.CompletionConfig() + + client.get_completion_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_completion_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetCompletionConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + 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_completion_config(request) + + +def test_get_completion_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.CompletionConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + + # 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 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_completion_config(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/completionConfig}" % client.transport._host, args[1]) + + +def test_get_completion_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + + +def test_get_completion_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateCompletionConfigRequest, + dict, +]) +def test_update_completion_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + request_init["completion_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig', 'matching_order': 'matching_order_value', 'max_suggestions': 1632, 'min_prefix_length': 1810, 'auto_learning': True, 'suggestions_input_config': {'big_query_source': {'partition_date': {'year': 433, 'month': 550, 'day': 318}, 'project_id': 'project_id_value', 'dataset_id': 'dataset_id_value', 'table_id': 'table_id_value', 'gcs_staging_dir': 'gcs_staging_dir_value', 'data_schema': 'data_schema_value'}}, 'last_suggestions_import_operation': 'last_suggestions_import_operation_value', 'denylist_input_config': {}, 'last_denylist_import_operation': 'last_denylist_import_operation_value', 'allowlist_input_config': {}, 'last_allowlist_import_operation': 'last_allowlist_import_operation_value'} + 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 = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_completion_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_update_completion_config_rest_required_fields(request_type=catalog_service.UpdateCompletionConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_completion_config._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_completion_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.CompletionConfig() + # 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 + + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_completion_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_completion_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_completion_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("completionConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_completion_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_completion_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_completion_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateCompletionConfigRequest.pb(catalog_service.UpdateCompletionConfigRequest()) + 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 = catalog.CompletionConfig.to_json(catalog.CompletionConfig()) + + request = catalog_service.UpdateCompletionConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.CompletionConfig() + + client.update_completion_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_completion_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateCompletionConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + request_init["completion_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig', 'matching_order': 'matching_order_value', 'max_suggestions': 1632, 'min_prefix_length': 1810, 'auto_learning': True, 'suggestions_input_config': {'big_query_source': {'partition_date': {'year': 433, 'month': 550, 'day': 318}, 'project_id': 'project_id_value', 'dataset_id': 'dataset_id_value', 'table_id': 'table_id_value', 'gcs_staging_dir': 'gcs_staging_dir_value', 'data_schema': 'data_schema_value'}}, 'last_suggestions_import_operation': 'last_suggestions_import_operation_value', 'denylist_input_config': {}, 'last_denylist_import_operation': 'last_denylist_import_operation_value', 'allowlist_input_config': {}, 'last_allowlist_import_operation': 'last_allowlist_import_operation_value'} + 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_completion_config(request) + + +def test_update_completion_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.CompletionConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + + # get truthy value for each flattened field + mock_args = dict( + completion_config=catalog.CompletionConfig(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 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_completion_config(**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/v2alpha/{completion_config.name=projects/*/locations/*/catalogs/*/completionConfig}" % client.transport._host, args[1]) + + +def test_update_completion_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_completion_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetAttributesConfigRequest, + dict, +]) +def test_get_attributes_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_attributes_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_get_attributes_config_rest_required_fields(request_type=catalog_service.GetAttributesConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_attributes_config._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_attributes_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_attributes_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_attributes_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_attributes_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_attributes_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_attributes_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_attributes_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetAttributesConfigRequest.pb(catalog_service.GetAttributesConfigRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.GetAttributesConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.get_attributes_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_attributes_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetAttributesConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_attributes_config(request) + + +def test_get_attributes_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.AttributesConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + + # 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 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_attributes_config(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/attributesConfig}" % client.transport._host, args[1]) + + +def test_get_attributes_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + + +def test_get_attributes_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateAttributesConfigRequest, + dict, +]) +def test_update_attributes_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + request_init["attributes_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig', 'catalog_attributes': {}, 'attribute_config_level': 1} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_attributes_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_update_attributes_config_rest_required_fields(request_type=catalog_service.UpdateAttributesConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_attributes_config._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_attributes_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_attributes_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_attributes_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_attributes_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("attributesConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_attributes_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_attributes_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_attributes_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateAttributesConfigRequest.pb(catalog_service.UpdateAttributesConfigRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.UpdateAttributesConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.update_attributes_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_attributes_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateAttributesConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + request_init["attributes_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig', 'catalog_attributes': {}, 'attribute_config_level': 1} + 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_attributes_config(request) + + +def test_update_attributes_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.AttributesConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + + # get truthy value for each flattened field + mock_args = dict( + attributes_config=catalog.AttributesConfig(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 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_attributes_config(**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/v2alpha/{attributes_config.name=projects/*/locations/*/catalogs/*/attributesConfig}" % client.transport._host, args[1]) + + +def test_update_attributes_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_attributes_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.AddCatalogAttributeRequest, + dict, +]) +def test_add_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_add_catalog_attribute_rest_required_fields(request_type=catalog_service.AddCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + 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_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "catalogAttribute", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_add_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_add_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.AddCatalogAttributeRequest.pb(catalog_service.AddCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.AddCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.add_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.AddCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_catalog_attribute(request) + + +def test_add_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.RemoveCatalogAttributeRequest, + dict, +]) +def test_remove_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_remove_catalog_attribute_rest_required_fields(request_type=catalog_service.RemoveCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + request_init["key"] = "" + 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_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + jsonified_request["key"] = 'key_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + assert "key" in jsonified_request + assert jsonified_request["key"] == 'key_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "key", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_remove_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_remove_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.RemoveCatalogAttributeRequest.pb(catalog_service.RemoveCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.RemoveCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.remove_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.RemoveCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_catalog_attribute(request) + + +def test_remove_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.BatchRemoveCatalogAttributesRequest, + dict, +]) +def test_batch_remove_catalog_attributes_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=['deleted_catalog_attributes_value'], + reset_catalog_attributes=['reset_catalog_attributes_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.BatchRemoveCatalogAttributesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_remove_catalog_attributes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ['deleted_catalog_attributes_value'] + assert response.reset_catalog_attributes == ['reset_catalog_attributes_value'] + + +def test_batch_remove_catalog_attributes_rest_required_fields(request_type=catalog_service.BatchRemoveCatalogAttributesRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + request_init["attribute_keys"] = "" + 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_remove_catalog_attributes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + jsonified_request["attributeKeys"] = 'attribute_keys_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_remove_catalog_attributes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + assert "attributeKeys" in jsonified_request + assert jsonified_request["attributeKeys"] == 'attribute_keys_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog_service.BatchRemoveCatalogAttributesResponse() + # 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 + + pb_return_value = catalog_service.BatchRemoveCatalogAttributesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_remove_catalog_attributes(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_remove_catalog_attributes_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_remove_catalog_attributes._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "attributeKeys", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_remove_catalog_attributes_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_batch_remove_catalog_attributes") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_batch_remove_catalog_attributes") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.BatchRemoveCatalogAttributesRequest.pb(catalog_service.BatchRemoveCatalogAttributesRequest()) + 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 = catalog_service.BatchRemoveCatalogAttributesResponse.to_json(catalog_service.BatchRemoveCatalogAttributesResponse()) + + request = catalog_service.BatchRemoveCatalogAttributesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.BatchRemoveCatalogAttributesResponse() + + client.batch_remove_catalog_attributes(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_remove_catalog_attributes_rest_bad_request(transport: str = 'rest', request_type=catalog_service.BatchRemoveCatalogAttributesRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_remove_catalog_attributes(request) + + +def test_batch_remove_catalog_attributes_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ReplaceCatalogAttributeRequest, + dict, +]) +def test_replace_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.replace_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_replace_catalog_attribute_rest_required_fields(request_type=catalog_service.ReplaceCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + 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()).replace_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).replace_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.replace_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_replace_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.replace_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "catalogAttribute", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_replace_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_replace_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_replace_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.ReplaceCatalogAttributeRequest.pb(catalog_service.ReplaceCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.ReplaceCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.replace_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_replace_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.ReplaceCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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.replace_catalog_attribute(request) + + +def test_replace_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CatalogServiceClient( + 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 = CatalogServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CatalogServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CatalogServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + transports.CatalogServiceRestTransport, +]) +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 = CatalogServiceClient.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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CatalogServiceGrpcTransport, + ) + +def test_catalog_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_catalog_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.catalog_service.transports.CatalogServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_catalogs', + 'update_catalog', + 'set_default_branch', + 'get_default_branch', + 'get_completion_config', + 'update_completion_config', + 'get_attributes_config', + 'update_attributes_config', + 'add_catalog_attribute', + 'remove_catalog_attribute', + 'batch_remove_catalog_attributes', + 'replace_catalog_attribute', + 'get_operation', + 'list_operations', + ) + 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_catalog_service_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.retail_v2alpha.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_catalog_service_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.retail_v2alpha.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport() + adc.assert_called_once() + + +def test_catalog_service_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) + CatalogServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + ], +) +def test_catalog_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + transports.CatalogServiceRestTransport, + ], +) +def test_catalog_service_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.CatalogServiceGrpcTransport, grpc_helpers), + (transports.CatalogServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_catalog_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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_catalog_service_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.CatalogServiceRestTransport ( + 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_catalog_service_host_no_port(transport_name): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_catalog_service_host_with_port(transport_name): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_catalog_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CatalogServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CatalogServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_catalogs._session + session2 = client2.transport.list_catalogs._session + assert session1 != session2 + session1 = client1.transport.update_catalog._session + session2 = client2.transport.update_catalog._session + assert session1 != session2 + session1 = client1.transport.set_default_branch._session + session2 = client2.transport.set_default_branch._session + assert session1 != session2 + session1 = client1.transport.get_default_branch._session + session2 = client2.transport.get_default_branch._session + assert session1 != session2 + session1 = client1.transport.get_completion_config._session + session2 = client2.transport.get_completion_config._session + assert session1 != session2 + session1 = client1.transport.update_completion_config._session + session2 = client2.transport.update_completion_config._session + assert session1 != session2 + session1 = client1.transport.get_attributes_config._session + session2 = client2.transport.get_attributes_config._session + assert session1 != session2 + session1 = client1.transport.update_attributes_config._session + session2 = client2.transport.update_attributes_config._session + assert session1 != session2 + session1 = client1.transport.add_catalog_attribute._session + session2 = client2.transport.add_catalog_attribute._session + assert session1 != session2 + session1 = client1.transport.remove_catalog_attribute._session + session2 = client2.transport.remove_catalog_attribute._session + assert session1 != session2 + session1 = client1.transport.batch_remove_catalog_attributes._session + session2 = client2.transport.batch_remove_catalog_attributes._session + assert session1 != session2 + session1 = client1.transport.replace_catalog_attribute._session + session2 = client2.transport.replace_catalog_attribute._session + assert session1 != session2 +def test_catalog_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcTransport( + 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_catalog_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcAsyncIOTransport( + 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.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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_attributes_config_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/attributesConfig".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.attributes_config_path(project, location, catalog) + assert expected == actual + + +def test_parse_attributes_config_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = CatalogServiceClient.attributes_config_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_attributes_config_path(path) + assert expected == actual + +def test_branch_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + branch = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = CatalogServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "branch": "clam", + } + path = CatalogServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_branch_path(path) + assert expected == actual + +def test_catalog_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "catalog": "mussel", + } + path = CatalogServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_completion_config_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/completionConfig".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.completion_config_path(project, location, catalog) + assert expected == actual + + +def test_parse_completion_config_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + } + path = CatalogServiceClient.completion_config_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_completion_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CatalogServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = CatalogServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = CatalogServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = CatalogServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CatalogServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = CatalogServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = CatalogServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = CatalogServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CatalogServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = CatalogServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.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.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CatalogServiceClient.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 = CatalogServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = CatalogServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = CatalogServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = CatalogServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = CatalogServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CatalogServiceClient( + 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 = CatalogServiceClient( + 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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_completion_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_completion_service.py new file mode 100644 index 00000000..67cb847e --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_completion_service.py @@ -0,0 +1,2307 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.completion_service import CompletionServiceAsyncClient +from google.cloud.retail_v2alpha.services.completion_service import CompletionServiceClient +from google.cloud.retail_v2alpha.services.completion_service import transports +from google.cloud.retail_v2alpha.types import completion_service +from google.cloud.retail_v2alpha.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.type import date_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 CompletionServiceClient._get_default_mtls_endpoint(None) is None + assert CompletionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (CompletionServiceClient, "grpc"), + (CompletionServiceAsyncClient, "grpc_asyncio"), + (CompletionServiceClient, "rest"), +]) +def test_completion_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CompletionServiceGrpcTransport, "grpc"), + (transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.CompletionServiceRestTransport, "rest"), +]) +def test_completion_service_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", [ + (CompletionServiceClient, "grpc"), + (CompletionServiceAsyncClient, "grpc_asyncio"), + (CompletionServiceClient, "rest"), +]) +def test_completion_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_completion_service_client_get_transport_class(): + transport = CompletionServiceClient.get_transport_class() + available_transports = [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceRestTransport, + ] + assert transport in available_transports + + transport = CompletionServiceClient.get_transport_class("grpc") + assert transport == transports.CompletionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_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(CompletionServiceClient, '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(CompletionServiceClient, '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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "true"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "false"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", "true"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_completion_service_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", [ + CompletionServiceClient, CompletionServiceAsyncClient +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest"), +]) +def test_completion_service_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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", grpc_helpers), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", None), +]) +def test_completion_service_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_completion_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.completion_service.transports.CompletionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CompletionServiceClient( + 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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", grpc_helpers), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_completion_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + completion_service.CompleteQueryRequest, + dict, +]) +def test_complete_query(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + ) + response = client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +def test_complete_query_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 = CompletionServiceClient( + 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.complete_query), + '__call__') as call: + client.complete_query() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + +@pytest.mark.asyncio +async def test_complete_query_async(transport: str = 'grpc_asyncio', request_type=completion_service.CompleteQueryRequest): + client = CompletionServiceAsyncClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + )) + response = await client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +@pytest.mark.asyncio +async def test_complete_query_async_from_dict(): + await test_complete_query_async(request_type=dict) + + +def test_complete_query_field_headers(): + client = CompletionServiceClient( + 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 = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = completion_service.CompleteQueryResponse() + client.complete_query(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_complete_query_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse()) + await client.complete_query(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportCompletionDataRequest, + dict, +]) +def test_import_completion_data(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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_completion_data), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_completion_data_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 = CompletionServiceClient( + 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_completion_data), + '__call__') as call: + client.import_completion_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + +@pytest.mark.asyncio +async def test_import_completion_data_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportCompletionDataRequest): + client = CompletionServiceAsyncClient( + 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_completion_data), + '__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_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_completion_data_async_from_dict(): + await test_import_completion_data_async(request_type=dict) + + +def test_import_completion_data_field_headers(): + client = CompletionServiceClient( + 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 = import_config.ImportCompletionDataRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_completion_data(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_completion_data_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = import_config.ImportCompletionDataRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_completion_data(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'] + + +@pytest.mark.parametrize("request_type", [ + completion_service.CompleteQueryRequest, + dict, +]) +def test_complete_query_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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 = completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = completion_service.CompleteQueryResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.complete_query(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +def test_complete_query_rest_required_fields(request_type=completion_service.CompleteQueryRequest): + transport_class = transports.CompletionServiceRestTransport + + request_init = {} + request_init["catalog"] = "" + request_init["query"] = "" + 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 + assert "query" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).complete_query._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "query" in jsonified_request + assert jsonified_request["query"] == request_init["query"] + + jsonified_request["catalog"] = 'catalog_value' + jsonified_request["query"] = 'query_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).complete_query._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dataset", "device_type", "enable_attribute_suggestions", "entity", "language_codes", "max_suggestions", "query", "visitor_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "catalog" in jsonified_request + assert jsonified_request["catalog"] == 'catalog_value' + assert "query" in jsonified_request + assert jsonified_request["query"] == 'query_value' + + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = completion_service.CompleteQueryResponse() + # 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 + + pb_return_value = completion_service.CompleteQueryResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.complete_query(request) + + expected_params = [ + ( + "query", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_complete_query_rest_unset_required_fields(): + transport = transports.CompletionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.complete_query._get_unset_required_fields({}) + assert set(unset_fields) == (set(("dataset", "deviceType", "enableAttributeSuggestions", "entity", "languageCodes", "maxSuggestions", "query", "visitorId", )) & set(("catalog", "query", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_complete_query_rest_interceptors(null_interceptor): + transport = transports.CompletionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CompletionServiceRestInterceptor(), + ) + client = CompletionServiceClient(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.CompletionServiceRestInterceptor, "post_complete_query") as post, \ + mock.patch.object(transports.CompletionServiceRestInterceptor, "pre_complete_query") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = completion_service.CompleteQueryRequest.pb(completion_service.CompleteQueryRequest()) + 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 = completion_service.CompleteQueryResponse.to_json(completion_service.CompleteQueryResponse()) + + request = completion_service.CompleteQueryRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = completion_service.CompleteQueryResponse() + + client.complete_query(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_complete_query_rest_bad_request(transport: str = 'rest', request_type=completion_service.CompleteQueryRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.complete_query(request) + + +def test_complete_query_rest_error(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportCompletionDataRequest, + dict, +]) +def test_import_completion_data_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_completion_data(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_completion_data_rest_required_fields(request_type=import_config.ImportCompletionDataRequest): + transport_class = transports.CompletionServiceRestTransport + + 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_completion_data._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_completion_data._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 = CompletionServiceClient( + 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_completion_data(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_completion_data_rest_unset_required_fields(): + transport = transports.CompletionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_completion_data._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_completion_data_rest_interceptors(null_interceptor): + transport = transports.CompletionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CompletionServiceRestInterceptor(), + ) + client = CompletionServiceClient(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.CompletionServiceRestInterceptor, "post_import_completion_data") as post, \ + mock.patch.object(transports.CompletionServiceRestInterceptor, "pre_import_completion_data") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportCompletionDataRequest.pb(import_config.ImportCompletionDataRequest()) + 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 = import_config.ImportCompletionDataRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_completion_data(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_completion_data_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportCompletionDataRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.import_completion_data(request) + + +def test_import_completion_data_rest_error(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CompletionServiceClient( + 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 = CompletionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CompletionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CompletionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + transports.CompletionServiceRestTransport, +]) +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 = CompletionServiceClient.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 = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CompletionServiceGrpcTransport, + ) + +def test_completion_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_completion_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.completion_service.transports.CompletionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'complete_query', + 'import_completion_data', + 'get_operation', + 'list_operations', + ) + 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_completion_service_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.retail_v2alpha.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_completion_service_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.retail_v2alpha.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport() + adc.assert_called_once() + + +def test_completion_service_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) + CompletionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + ], +) +def test_completion_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + transports.CompletionServiceRestTransport, + ], +) +def test_completion_service_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.CompletionServiceGrpcTransport, grpc_helpers), + (transports.CompletionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_completion_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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_completion_service_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.CompletionServiceRestTransport ( + 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_completion_service_rest_lro_client(): + client = CompletionServiceClient( + 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_completion_service_host_no_port(transport_name): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_completion_service_host_with_port(transport_name): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_completion_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CompletionServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CompletionServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.complete_query._session + session2 = client2.transport.complete_query._session + assert session1 != session2 + session1 = client1.transport.import_completion_data._session + session2 = client2.transport.import_completion_data._session + assert session1 != session2 +def test_completion_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcTransport( + 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_completion_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcAsyncIOTransport( + 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.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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_completion_service_grpc_lro_client(): + client = CompletionServiceClient( + 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_completion_service_grpc_lro_async_client(): + client = CompletionServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CompletionServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = CompletionServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CompletionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = CompletionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = CompletionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = CompletionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CompletionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = CompletionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = CompletionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = CompletionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CompletionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = CompletionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.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.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CompletionServiceClient.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 = CompletionServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = CompletionServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = CompletionServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = CompletionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = CompletionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CompletionServiceClient( + 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 = CompletionServiceClient( + 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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_control_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_control_service.py new file mode 100644 index 00000000..088cd148 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_control_service.py @@ -0,0 +1,4301 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.control_service import ControlServiceAsyncClient +from google.cloud.retail_v2alpha.services.control_service import ControlServiceClient +from google.cloud.retail_v2alpha.services.control_service import pagers +from google.cloud.retail_v2alpha.services.control_service import transports +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import control +from google.cloud.retail_v2alpha.types import control as gcr_control +from google.cloud.retail_v2alpha.types import control_service +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_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 ControlServiceClient._get_default_mtls_endpoint(None) is None + assert ControlServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ControlServiceClient, "grpc"), + (ControlServiceAsyncClient, "grpc_asyncio"), + (ControlServiceClient, "rest"), +]) +def test_control_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ControlServiceGrpcTransport, "grpc"), + (transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ControlServiceRestTransport, "rest"), +]) +def test_control_service_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", [ + (ControlServiceClient, "grpc"), + (ControlServiceAsyncClient, "grpc_asyncio"), + (ControlServiceClient, "rest"), +]) +def test_control_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_control_service_client_get_transport_class(): + transport = ControlServiceClient.get_transport_class() + available_transports = [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceRestTransport, + ] + assert transport in available_transports + + transport = ControlServiceClient.get_transport_class("grpc") + assert transport == transports.ControlServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest"), +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +def test_control_service_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(ControlServiceClient, '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(ControlServiceClient, '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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", "true"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", "false"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", "true"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_control_service_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", [ + ControlServiceClient, ControlServiceAsyncClient +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +def test_control_service_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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest"), +]) +def test_control_service_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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", grpc_helpers), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", None), +]) +def test_control_service_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_control_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.control_service.transports.ControlServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ControlServiceClient( + 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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", grpc_helpers), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_control_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.CreateControlRequest, + dict, +]) +def test_create_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.create_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_create_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.create_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + +@pytest.mark.asyncio +async def test_create_control_async(transport: str = 'grpc_asyncio', request_type=control_service.CreateControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.create_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_create_control_async_from_dict(): + await test_create_control_async(request_type=dict) + + +def test_create_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.CreateControlRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + call.return_value = gcr_control.Control() + client.create_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.CreateControlRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + await client.create_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_control( + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))) + assert arg == mock_val + arg = args[0].control_id + mock_val = 'control_id_value' + assert arg == mock_val + + +def test_create_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + +@pytest.mark.asyncio +async def test_create_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_control( + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))) + assert arg == mock_val + arg = args[0].control_id + mock_val = 'control_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.DeleteControlRequest, + dict, +]) +def test_delete_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.delete_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + +@pytest.mark.asyncio +async def test_delete_control_async(transport: str = 'grpc_asyncio', request_type=control_service.DeleteControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_control_async_from_dict(): + await test_delete_control_async(request_type=dict) + + +def test_delete_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.DeleteControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__call__') as call: + call.return_value = None + client.delete_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.DeleteControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__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_control( + 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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__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_control( + 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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.UpdateControlRequest, + dict, +]) +def test_update_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.update_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_update_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.update_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + +@pytest.mark.asyncio +async def test_update_control_async(transport: str = 'grpc_asyncio', request_type=control_service.UpdateControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.update_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_update_control_async_from_dict(): + await test_update_control_async(request_type=dict) + + +def test_update_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.UpdateControlRequest() + + request.control.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + call.return_value = gcr_control.Control() + client.update_control(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', + 'control.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.UpdateControlRequest() + + request.control.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + await client.update_control(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', + 'control.name=name_value', + ) in kw['metadata'] + + +def test_update_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_control( + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_control( + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.GetControlRequest, + dict, +]) +def test_get_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.get_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_get_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.get_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + +@pytest.mark.asyncio +async def test_get_control_async(transport: str = 'grpc_asyncio', request_type=control_service.GetControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.get_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_get_control_async_from_dict(): + await test_get_control_async(request_type=dict) + + +def test_get_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.GetControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + call.return_value = control.Control() + client.get_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.GetControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control.Control()) + await client.get_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_control( + 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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_control( + 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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.ListControlsRequest, + dict, +]) +def test_list_controls(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_controls(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_controls_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 = ControlServiceClient( + 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_controls), + '__call__') as call: + client.list_controls() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + +@pytest.mark.asyncio +async def test_list_controls_async(transport: str = 'grpc_asyncio', request_type=control_service.ListControlsRequest): + client = ControlServiceAsyncClient( + 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_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_controls(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_controls_async_from_dict(): + await test_list_controls_async(request_type=dict) + + +def test_list_controls_field_headers(): + client = ControlServiceClient( + 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 = control_service.ListControlsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + call.return_value = control_service.ListControlsResponse() + client.list_controls(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_controls_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.ListControlsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse()) + await client.list_controls(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_controls_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_controls( + 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_controls_flattened_error(): + client = ControlServiceClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_controls_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_controls( + 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_controls_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + + +def test_list_controls_pager(transport_name: str = "grpc"): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_controls(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, control.Control) + for i in results) +def test_list_controls_pages(transport_name: str = "grpc"): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + pages = list(client.list_controls(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_controls_async_pager(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_controls(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, control.Control) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_controls_async_pages(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + 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_controls(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", [ + control_service.CreateControlRequest, + dict, +]) +def test_create_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'name_value', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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 = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_create_control_rest_required_fields(request_type=control_service.CreateControlRequest): + transport_class = transports.ControlServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["control_id"] = "" + 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 + assert "controlId" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == request_init["control_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_control._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("control_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' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_control.Control() + # 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 + + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_control(request) + + expected_params = [ + ( + "controlId", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(("controlId", )) & set(("parent", "control", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_create_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_create_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.CreateControlRequest.pb(control_service.CreateControlRequest()) + 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 = gcr_control.Control.to_json(gcr_control.Control()) + + request = control_service.CreateControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_control.Control() + + client.create_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_control_rest_bad_request(transport: str = 'rest', request_type=control_service.CreateControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'name_value', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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_control(request) + + +def test_create_control_rest_flattened(): + client = ControlServiceClient( + 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 = gcr_control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_control(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/controls" % client.transport._host, args[1]) + + +def test_create_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + + +def test_create_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.DeleteControlRequest, + dict, +]) +def test_delete_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_control_rest_required_fields(request_type=control_service.DeleteControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + 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_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "pre_delete_control") as pre: + pre.assert_not_called() + pb_message = control_service.DeleteControlRequest.pb(control_service.DeleteControlRequest()) + 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 = control_service.DeleteControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_control_rest_bad_request(transport: str = 'rest', request_type=control_service.DeleteControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + +def test_delete_control_rest_flattened(): + client = ControlServiceClient( + 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/catalogs/sample3/controls/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_control(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_delete_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + + +def test_delete_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.UpdateControlRequest, + dict, +]) +def test_update_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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 = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_update_control_rest_required_fields(request_type=control_service.UpdateControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_control.Control() + # 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 + + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("control", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_update_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_update_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.UpdateControlRequest.pb(control_service.UpdateControlRequest()) + 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 = gcr_control.Control.to_json(gcr_control.Control()) + + request = control_service.UpdateControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_control.Control() + + client.update_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_control_rest_bad_request(transport: str = 'rest', request_type=control_service.UpdateControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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_control(request) + + +def test_update_control_rest_flattened(): + client = ControlServiceClient( + 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 = gcr_control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_control(**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/v2alpha/{control.name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_update_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.GetControlRequest, + dict, +]) +def test_get_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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 = control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_get_control_rest_required_fields(request_type=control_service.GetControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = control.Control() + # 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 + + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_get_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_get_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.GetControlRequest.pb(control_service.GetControlRequest()) + 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 = control.Control.to_json(control.Control()) + + request = control_service.GetControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = control.Control() + + client.get_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_control_rest_bad_request(transport: str = 'rest', request_type=control_service.GetControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + +def test_get_control_rest_flattened(): + client = ControlServiceClient( + 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 = control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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 + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_control(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_get_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + + +def test_get_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.ListControlsRequest, + dict, +]) +def test_list_controls_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = control_service.ListControlsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_controls(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_controls_rest_required_fields(request_type=control_service.ListControlsRequest): + transport_class = transports.ControlServiceRestTransport + + 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_controls._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_controls._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("filter", "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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = control_service.ListControlsResponse() + # 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 + + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_controls(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_controls_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_controls._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_controls_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_list_controls") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_list_controls") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.ListControlsRequest.pb(control_service.ListControlsRequest()) + 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 = control_service.ListControlsResponse.to_json(control_service.ListControlsResponse()) + + request = control_service.ListControlsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = control_service.ListControlsResponse() + + client.list_controls(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_controls_rest_bad_request(transport: str = 'rest', request_type=control_service.ListControlsRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_controls(request) + + +def test_list_controls_rest_flattened(): + client = ControlServiceClient( + 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 = control_service.ListControlsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_controls(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/controls" % client.transport._host, args[1]) + + +def test_list_controls_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + + +def test_list_controls_rest_pager(transport: str = 'rest'): + client = ControlServiceClient( + 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 = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(control_service.ListControlsResponse.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/catalogs/sample3'} + + pager = client.list_controls(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, control.Control) + for i in results) + + pages = list(client.list_controls(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ControlServiceClient( + 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 = ControlServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ControlServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ControlServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + transports.ControlServiceRestTransport, +]) +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 = ControlServiceClient.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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ControlServiceGrpcTransport, + ) + +def test_control_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ControlServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_control_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.control_service.transports.ControlServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ControlServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_control', + 'delete_control', + 'update_control', + 'get_control', + 'list_controls', + 'get_operation', + 'list_operations', + ) + 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_control_service_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.retail_v2alpha.services.control_service.transports.ControlServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ControlServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_control_service_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.retail_v2alpha.services.control_service.transports.ControlServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ControlServiceTransport() + adc.assert_called_once() + + +def test_control_service_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) + ControlServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + ], +) +def test_control_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + transports.ControlServiceRestTransport, + ], +) +def test_control_service_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.ControlServiceGrpcTransport, grpc_helpers), + (transports.ControlServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_control_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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_control_service_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.ControlServiceRestTransport ( + 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_control_service_host_no_port(transport_name): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_control_service_host_with_port(transport_name): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_control_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ControlServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ControlServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_control._session + session2 = client2.transport.create_control._session + assert session1 != session2 + session1 = client1.transport.delete_control._session + session2 = client2.transport.delete_control._session + assert session1 != session2 + session1 = client1.transport.update_control._session + session2 = client2.transport.update_control._session + assert session1 != session2 + session1 = client1.transport.get_control._session + session2 = client2.transport.get_control._session + assert session1 != session2 + session1 = client1.transport.list_controls._session + session2 = client2.transport.list_controls._session + assert session1 != session2 +def test_control_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ControlServiceGrpcTransport( + 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_control_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ControlServiceGrpcAsyncIOTransport( + 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.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ControlServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ControlServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_control_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + control = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/controls/{control}".format(project=project, location=location, catalog=catalog, control=control, ) + actual = ControlServiceClient.control_path(project, location, catalog, control) + assert expected == actual + + +def test_parse_control_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "control": "clam", + } + path = ControlServiceClient.control_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_control_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ControlServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ControlServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ControlServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ControlServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ControlServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ControlServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ControlServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ControlServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ControlServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ControlServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.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.ControlServiceTransport, '_prep_wrapped_messages') as prep: + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ControlServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ControlServiceClient.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 = ControlServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ControlServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ControlServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ControlServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ControlServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ControlServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ControlServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ControlServiceClient( + 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 = ControlServiceClient( + 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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_merchant_center_account_link_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_merchant_center_account_link_service.py new file mode 100644 index 00000000..25b103d1 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_merchant_center_account_link_service.py @@ -0,0 +1,3045 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.merchant_center_account_link_service import MerchantCenterAccountLinkServiceAsyncClient +from google.cloud.retail_v2alpha.services.merchant_center_account_link_service import MerchantCenterAccountLinkServiceClient +from google.cloud.retail_v2alpha.services.merchant_center_account_link_service import transports +from google.cloud.retail_v2alpha.types import merchant_center_account_link +from google.cloud.retail_v2alpha.types import merchant_center_account_link as gcr_merchant_center_account_link +from google.cloud.retail_v2alpha.types import merchant_center_account_link_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +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 MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(None) is None + assert MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert MerchantCenterAccountLinkServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (MerchantCenterAccountLinkServiceClient, "grpc"), + (MerchantCenterAccountLinkServiceAsyncClient, "grpc_asyncio"), + (MerchantCenterAccountLinkServiceClient, "rest"), +]) +def test_merchant_center_account_link_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc"), + (transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.MerchantCenterAccountLinkServiceRestTransport, "rest"), +]) +def test_merchant_center_account_link_service_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", [ + (MerchantCenterAccountLinkServiceClient, "grpc"), + (MerchantCenterAccountLinkServiceAsyncClient, "grpc_asyncio"), + (MerchantCenterAccountLinkServiceClient, "rest"), +]) +def test_merchant_center_account_link_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_merchant_center_account_link_service_client_get_transport_class(): + transport = MerchantCenterAccountLinkServiceClient.get_transport_class() + available_transports = [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceRestTransport, + ] + assert transport in available_transports + + transport = MerchantCenterAccountLinkServiceClient.get_transport_class("grpc") + assert transport == transports.MerchantCenterAccountLinkServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc"), + (MerchantCenterAccountLinkServiceAsyncClient, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceRestTransport, "rest"), +]) +@mock.patch.object(MerchantCenterAccountLinkServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MerchantCenterAccountLinkServiceClient)) +@mock.patch.object(MerchantCenterAccountLinkServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MerchantCenterAccountLinkServiceAsyncClient)) +def test_merchant_center_account_link_service_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(MerchantCenterAccountLinkServiceClient, '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(MerchantCenterAccountLinkServiceClient, '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", [ + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc", "true"), + (MerchantCenterAccountLinkServiceAsyncClient, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc", "false"), + (MerchantCenterAccountLinkServiceAsyncClient, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceRestTransport, "rest", "true"), + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(MerchantCenterAccountLinkServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MerchantCenterAccountLinkServiceClient)) +@mock.patch.object(MerchantCenterAccountLinkServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MerchantCenterAccountLinkServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_merchant_center_account_link_service_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", [ + MerchantCenterAccountLinkServiceClient, MerchantCenterAccountLinkServiceAsyncClient +]) +@mock.patch.object(MerchantCenterAccountLinkServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MerchantCenterAccountLinkServiceClient)) +@mock.patch.object(MerchantCenterAccountLinkServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(MerchantCenterAccountLinkServiceAsyncClient)) +def test_merchant_center_account_link_service_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", [ + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc"), + (MerchantCenterAccountLinkServiceAsyncClient, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceRestTransport, "rest"), +]) +def test_merchant_center_account_link_service_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", [ + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc", grpc_helpers), + (MerchantCenterAccountLinkServiceAsyncClient, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceRestTransport, "rest", None), +]) +def test_merchant_center_account_link_service_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_merchant_center_account_link_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = MerchantCenterAccountLinkServiceClient( + 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", [ + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceGrpcTransport, "grpc", grpc_helpers), + (MerchantCenterAccountLinkServiceAsyncClient, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_merchant_center_account_link_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + dict, +]) +def test_list_merchant_center_account_links(request_type, transport: str = 'grpc'): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_links), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse( + ) + response = client.list_merchant_center_account_links(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse) + + +def test_list_merchant_center_account_links_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 = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_links), + '__call__') as call: + client.list_merchant_center_account_links() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_async(transport: str = 'grpc_asyncio', request_type=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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_merchant_center_account_links), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse( + )) + response = await client.list_merchant_center_account_links(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse) + + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_async_from_dict(): + await test_list_merchant_center_account_links_async(request_type=dict) + + +def test_list_merchant_center_account_links_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + 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 = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), + '__call__') as call: + call.return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + client.list_merchant_center_account_links(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_merchant_center_account_links_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse()) + await client.list_merchant_center_account_links(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_merchant_center_account_links_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_merchant_center_account_links( + 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_merchant_center_account_links_flattened_error(): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_links( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_merchant_center_account_links_flattened_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_merchant_center_account_links), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_merchant_center_account_links( + 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_merchant_center_account_links_flattened_error_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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_merchant_center_account_links( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(), + parent='parent_value', + ) + + +@pytest.mark.parametrize("request_type", [ + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + dict, +]) +def test_create_merchant_center_account_link(request_type, transport: str = 'grpc'): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.create_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_merchant_center_account_link_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 = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link), + '__call__') as call: + client.create_merchant_center_account_link() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_async(transport: str = 'grpc_asyncio', request_type=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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_merchant_center_account_link), + '__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.create_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_async_from_dict(): + await test_create_merchant_center_account_link_async(request_type=dict) + + +def test_create_merchant_center_account_link_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + 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 = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.create_merchant_center_account_link(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_merchant_center_account_link_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.create_merchant_center_account_link(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_merchant_center_account_link_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), + '__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.create_merchant_center_account_link( + parent='parent_value', + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink(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].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].merchant_center_account_link + mock_val = gcr_merchant_center_account_link.MerchantCenterAccountLink(name='name_value') + assert arg == mock_val + + +def test_create_merchant_center_account_link_flattened_error(): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(), + parent='parent_value', + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink(name='name_value'), + ) + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_flattened_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_merchant_center_account_link), + '__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.create_merchant_center_account_link( + parent='parent_value', + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink(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].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].merchant_center_account_link + mock_val = gcr_merchant_center_account_link.MerchantCenterAccountLink(name='name_value') + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_merchant_center_account_link_flattened_error_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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_merchant_center_account_link( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(), + parent='parent_value', + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink(name='name_value'), + ) + + +@pytest.mark.parametrize("request_type", [ + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + dict, +]) +def test_delete_merchant_center_account_link(request_type, transport: str = 'grpc'): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_merchant_center_account_link_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 = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link), + '__call__') as call: + client.delete_merchant_center_account_link() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_async(transport: str = 'grpc_asyncio', request_type=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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_merchant_center_account_link), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_merchant_center_account_link(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_async_from_dict(): + await test_delete_merchant_center_account_link_async(request_type=dict) + + +def test_delete_merchant_center_account_link_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + 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 = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), + '__call__') as call: + call.return_value = None + client.delete_merchant_center_account_link(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_merchant_center_account_link_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_merchant_center_account_link(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_merchant_center_account_link_flattened(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), + '__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_merchant_center_account_link( + 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_merchant_center_account_link_flattened_error(): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_merchant_center_account_link_flattened_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_merchant_center_account_link), + '__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_merchant_center_account_link( + 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_merchant_center_account_link_flattened_error_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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_merchant_center_account_link( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest, + dict, +]) +def test_list_merchant_center_account_links_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse( + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_merchant_center_account_links(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse) + + +def test_list_merchant_center_account_links_rest_required_fields(request_type=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest): + transport_class = transports.MerchantCenterAccountLinkServiceRestTransport + + 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_merchant_center_account_links._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_merchant_center_account_links._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 = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + # 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 + + pb_return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_merchant_center_account_links(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_merchant_center_account_links_rest_unset_required_fields(): + transport = transports.MerchantCenterAccountLinkServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_merchant_center_account_links._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_merchant_center_account_links_rest_interceptors(null_interceptor): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.MerchantCenterAccountLinkServiceRestInterceptor(), + ) + client = MerchantCenterAccountLinkServiceClient(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.MerchantCenterAccountLinkServiceRestInterceptor, "post_list_merchant_center_account_links") as post, \ + mock.patch.object(transports.MerchantCenterAccountLinkServiceRestInterceptor, "pre_list_merchant_center_account_links") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest.pb(merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest()) + 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 = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.to_json(merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse()) + + request = merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + + client.list_merchant_center_account_links(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_merchant_center_account_links_rest_bad_request(transport: str = 'rest', request_type=merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_merchant_center_account_links(request) + + +def test_list_merchant_center_account_links_rest_flattened(): + client = MerchantCenterAccountLinkServiceClient( + 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 = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = merchant_center_account_link_service.ListMerchantCenterAccountLinksResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_merchant_center_account_links(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/merchantCenterAccountLinks" % client.transport._host, args[1]) + + +def test_list_merchant_center_account_links_rest_flattened_error(transport: str = 'rest'): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_links( + merchant_center_account_link_service.ListMerchantCenterAccountLinksRequest(), + parent='parent_value', + ) + + +def test_list_merchant_center_account_links_rest_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest, + dict, +]) +def test_create_merchant_center_account_link_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["merchant_center_account_link"] = {'name': 'name_value', 'id': 'id_value', 'merchant_center_account_id': 2730, 'branch_id': 'branch_id_value', 'feed_label': 'feed_label_value', 'language_code': 'language_code_value', 'feed_filters': [{'primary_feed_id': 1571, 'primary_feed_name': 'primary_feed_name_value'}], 'state': 1, 'project_id': 'project_id_value'} + 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.create_merchant_center_account_link(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_merchant_center_account_link_rest_required_fields(request_type=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest): + transport_class = transports.MerchantCenterAccountLinkServiceRestTransport + + 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_merchant_center_account_link._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_merchant_center_account_link._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 = MerchantCenterAccountLinkServiceClient( + 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.create_merchant_center_account_link(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_merchant_center_account_link_rest_unset_required_fields(): + transport = transports.MerchantCenterAccountLinkServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_merchant_center_account_link._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "merchantCenterAccountLink", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_merchant_center_account_link_rest_interceptors(null_interceptor): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.MerchantCenterAccountLinkServiceRestInterceptor(), + ) + client = MerchantCenterAccountLinkServiceClient(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.MerchantCenterAccountLinkServiceRestInterceptor, "post_create_merchant_center_account_link") as post, \ + mock.patch.object(transports.MerchantCenterAccountLinkServiceRestInterceptor, "pre_create_merchant_center_account_link") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest.pb(merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest()) + 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 = merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_merchant_center_account_link(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_merchant_center_account_link_rest_bad_request(transport: str = 'rest', request_type=merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["merchant_center_account_link"] = {'name': 'name_value', 'id': 'id_value', 'merchant_center_account_id': 2730, 'branch_id': 'branch_id_value', 'feed_label': 'feed_label_value', 'language_code': 'language_code_value', 'feed_filters': [{'primary_feed_id': 1571, 'primary_feed_name': 'primary_feed_name_value'}], 'state': 1, 'project_id': 'project_id_value'} + 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_merchant_center_account_link(request) + + +def test_create_merchant_center_account_link_rest_flattened(): + client = MerchantCenterAccountLinkServiceClient( + 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/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink(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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_merchant_center_account_link(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/merchantCenterAccountLinks" % client.transport._host, args[1]) + + +def test_create_merchant_center_account_link_rest_flattened_error(transport: str = 'rest'): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link( + merchant_center_account_link_service.CreateMerchantCenterAccountLinkRequest(), + parent='parent_value', + merchant_center_account_link=gcr_merchant_center_account_link.MerchantCenterAccountLink(name='name_value'), + ) + + +def test_create_merchant_center_account_link_rest_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest, + dict, +]) +def test_delete_merchant_center_account_link_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/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_merchant_center_account_link(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_merchant_center_account_link_rest_required_fields(request_type=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest): + transport_class = transports.MerchantCenterAccountLinkServiceRestTransport + + 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_merchant_center_account_link._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_merchant_center_account_link._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 = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_merchant_center_account_link_rest_unset_required_fields(): + transport = transports.MerchantCenterAccountLinkServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_merchant_center_account_link._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_merchant_center_account_link_rest_interceptors(null_interceptor): + transport = transports.MerchantCenterAccountLinkServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.MerchantCenterAccountLinkServiceRestInterceptor(), + ) + client = MerchantCenterAccountLinkServiceClient(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.MerchantCenterAccountLinkServiceRestInterceptor, "pre_delete_merchant_center_account_link") as pre: + pre.assert_not_called() + pb_message = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest.pb(merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest()) + 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 = merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_merchant_center_account_link(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_merchant_center_account_link_rest_bad_request(transport: str = 'rest', request_type=merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/merchantCenterAccountLinks/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_merchant_center_account_link(request) + + +def test_delete_merchant_center_account_link_rest_flattened(): + client = MerchantCenterAccountLinkServiceClient( + 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/catalogs/sample3/merchantCenterAccountLinks/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_merchant_center_account_link(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/merchantCenterAccountLinks/*}" % client.transport._host, args[1]) + + +def test_delete_merchant_center_account_link_rest_flattened_error(transport: str = 'rest'): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link( + merchant_center_account_link_service.DeleteMerchantCenterAccountLinkRequest(), + name='name_value', + ) + + +def test_delete_merchant_center_account_link_rest_error(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + 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 = MerchantCenterAccountLinkServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = MerchantCenterAccountLinkServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = MerchantCenterAccountLinkServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + transports.MerchantCenterAccountLinkServiceRestTransport, +]) +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 = MerchantCenterAccountLinkServiceClient.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 = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.MerchantCenterAccountLinkServiceGrpcTransport, + ) + +def test_merchant_center_account_link_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.MerchantCenterAccountLinkServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_merchant_center_account_link_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.MerchantCenterAccountLinkServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_merchant_center_account_links', + 'create_merchant_center_account_link', + 'delete_merchant_center_account_link', + 'get_operation', + 'list_operations', + ) + 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_merchant_center_account_link_service_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.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MerchantCenterAccountLinkServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_merchant_center_account_link_service_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.retail_v2alpha.services.merchant_center_account_link_service.transports.MerchantCenterAccountLinkServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.MerchantCenterAccountLinkServiceTransport() + adc.assert_called_once() + + +def test_merchant_center_account_link_service_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) + MerchantCenterAccountLinkServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + ], +) +def test_merchant_center_account_link_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.MerchantCenterAccountLinkServiceGrpcTransport, + transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, + transports.MerchantCenterAccountLinkServiceRestTransport, + ], +) +def test_merchant_center_account_link_service_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.MerchantCenterAccountLinkServiceGrpcTransport, grpc_helpers), + (transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_merchant_center_account_link_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.MerchantCenterAccountLinkServiceGrpcTransport, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport]) +def test_merchant_center_account_link_service_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_merchant_center_account_link_service_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.MerchantCenterAccountLinkServiceRestTransport ( + 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_merchant_center_account_link_service_rest_lro_client(): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link_service_host_no_port(transport_name): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_merchant_center_account_link_service_host_with_port(transport_name): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_merchant_center_account_link_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = MerchantCenterAccountLinkServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = MerchantCenterAccountLinkServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_merchant_center_account_links._session + session2 = client2.transport.list_merchant_center_account_links._session + assert session1 != session2 + session1 = client1.transport.create_merchant_center_account_link._session + session2 = client2.transport.create_merchant_center_account_link._session + assert session1 != session2 + session1 = client1.transport.delete_merchant_center_account_link._session + session2 = client2.transport.delete_merchant_center_account_link._session + assert session1 != session2 +def test_merchant_center_account_link_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.MerchantCenterAccountLinkServiceGrpcTransport( + 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_merchant_center_account_link_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport( + 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.MerchantCenterAccountLinkServiceGrpcTransport, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport]) +def test_merchant_center_account_link_service_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.MerchantCenterAccountLinkServiceGrpcTransport, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport]) +def test_merchant_center_account_link_service_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_merchant_center_account_link_service_grpc_lro_client(): + client = MerchantCenterAccountLinkServiceClient( + 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_merchant_center_account_link_service_grpc_lro_async_client(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = MerchantCenterAccountLinkServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = MerchantCenterAccountLinkServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_merchant_center_account_link_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + merchant_center_account_link = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/merchantCenterAccountLinks/{merchant_center_account_link}".format(project=project, location=location, catalog=catalog, merchant_center_account_link=merchant_center_account_link, ) + actual = MerchantCenterAccountLinkServiceClient.merchant_center_account_link_path(project, location, catalog, merchant_center_account_link) + assert expected == actual + + +def test_parse_merchant_center_account_link_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "merchant_center_account_link": "clam", + } + path = MerchantCenterAccountLinkServiceClient.merchant_center_account_link_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_merchant_center_account_link_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = MerchantCenterAccountLinkServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = MerchantCenterAccountLinkServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = MerchantCenterAccountLinkServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = MerchantCenterAccountLinkServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = MerchantCenterAccountLinkServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = MerchantCenterAccountLinkServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = MerchantCenterAccountLinkServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = MerchantCenterAccountLinkServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = MerchantCenterAccountLinkServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = MerchantCenterAccountLinkServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = MerchantCenterAccountLinkServiceClient.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.MerchantCenterAccountLinkServiceTransport, '_prep_wrapped_messages') as prep: + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.MerchantCenterAccountLinkServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = MerchantCenterAccountLinkServiceClient.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 = MerchantCenterAccountLinkServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = MerchantCenterAccountLinkServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = MerchantCenterAccountLinkServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = MerchantCenterAccountLinkServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = MerchantCenterAccountLinkServiceClient( + 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 = MerchantCenterAccountLinkServiceClient( + 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", [ + (MerchantCenterAccountLinkServiceClient, transports.MerchantCenterAccountLinkServiceGrpcTransport), + (MerchantCenterAccountLinkServiceAsyncClient, transports.MerchantCenterAccountLinkServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_model_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_model_service.py new file mode 100644 index 00000000..26182a68 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_model_service.py @@ -0,0 +1,5874 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.model_service import ModelServiceAsyncClient +from google.cloud.retail_v2alpha.services.model_service import ModelServiceClient +from google.cloud.retail_v2alpha.services.model_service import pagers +from google.cloud.retail_v2alpha.services.model_service import transports +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import model +from google.cloud.retail_v2alpha.types import model as gcr_model +from google.cloud.retail_v2alpha.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_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 ModelServiceClient._get_default_mtls_endpoint(None) is None + assert ModelServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), +]) +def test_model_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ModelServiceGrpcTransport, "grpc"), + (transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ModelServiceRestTransport, "rest"), +]) +def test_model_service_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", [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), +]) +def test_model_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_model_service_client_get_transport_class(): + transport = ModelServiceClient.get_transport_class() + available_transports = [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceRestTransport, + ] + assert transport in available_transports + + transport = ModelServiceClient.get_transport_class("grpc") + assert transport == transports.ModelServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +def test_model_service_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(ModelServiceClient, '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(ModelServiceClient, '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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "true"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "false"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "true"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_model_service_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", [ + ModelServiceClient, ModelServiceAsyncClient +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +def test_model_service_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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), +]) +def test_model_service_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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", grpc_helpers), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", None), +]) +def test_model_service_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_model_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.model_service.transports.ModelServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ModelServiceClient( + 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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", grpc_helpers), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_model_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.CreateModelRequest, + dict, +]) +def test_create_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.create_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + +@pytest.mark.asyncio +async def test_create_model_async(transport: str = 'grpc_asyncio', request_type=model_service.CreateModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__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.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_model_async_from_dict(): + await test_create_model_async(request_type=dict) + + +def test_create_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.CreateModelRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.create_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.CreateModelRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.create_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__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.create_model( + parent='parent_value', + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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].model + mock_val = gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')) + assert arg == mock_val + + +def test_create_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')), + ) + +@pytest.mark.asyncio +async def test_create_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__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.create_model( + parent='parent_value', + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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].model + mock_val = gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')), + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.GetModelRequest, + dict, +]) +def test_get_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_get_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.get_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + +@pytest.mark.asyncio +async def test_get_model_async(transport: str = 'grpc_asyncio', request_type=model_service.GetModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + +def test_get_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.GetModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + call.return_value = model.Model() + client.get_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.GetModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.get_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_model( + 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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_model( + 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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.PauseModelRequest, + dict, +]) +def test_pause_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_pause_model_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 = ModelServiceClient( + 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.pause_model), + '__call__') as call: + client.pause_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + +@pytest.mark.asyncio +async def test_pause_model_async(transport: str = 'grpc_asyncio', request_type=model_service.PauseModelRequest): + client = ModelServiceAsyncClient( + 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.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_pause_model_async_from_dict(): + await test_pause_model_async(request_type=dict) + + +def test_pause_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.PauseModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + call.return_value = model.Model() + client.pause_model(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_pause_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.PauseModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.pause_model(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_pause_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.pause_model( + 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_pause_model_flattened_error(): + client = ModelServiceClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_pause_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.pause_model( + 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_pause_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ResumeModelRequest, + dict, +]) +def test_resume_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_resume_model_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 = ModelServiceClient( + 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.resume_model), + '__call__') as call: + client.resume_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + +@pytest.mark.asyncio +async def test_resume_model_async(transport: str = 'grpc_asyncio', request_type=model_service.ResumeModelRequest): + client = ModelServiceAsyncClient( + 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.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_resume_model_async_from_dict(): + await test_resume_model_async(request_type=dict) + + +def test_resume_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.ResumeModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + call.return_value = model.Model() + client.resume_model(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_resume_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.ResumeModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.resume_model(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_resume_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.resume_model( + 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_resume_model_flattened_error(): + client = ModelServiceClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_resume_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.resume_model( + 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_resume_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.DeleteModelRequest, + dict, +]) +def test_delete_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.delete_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + +@pytest.mark.asyncio +async def test_delete_model_async(transport: str = 'grpc_asyncio', request_type=model_service.DeleteModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_model_async_from_dict(): + await test_delete_model_async(request_type=dict) + + +def test_delete_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.DeleteModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__call__') as call: + call.return_value = None + client.delete_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.DeleteModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__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_model( + 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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__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_model( + 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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ListModelsRequest, + dict, +]) +def test_list_models(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_models_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 = ModelServiceClient( + 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_models), + '__call__') as call: + client.list_models() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + +@pytest.mark.asyncio +async def test_list_models_async(transport: str = 'grpc_asyncio', request_type=model_service.ListModelsRequest): + client = ModelServiceAsyncClient( + 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_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_models_async_from_dict(): + await test_list_models_async(request_type=dict) + + +def test_list_models_field_headers(): + client = ModelServiceClient( + 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 = model_service.ListModelsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + call.return_value = model_service.ListModelsResponse() + client.list_models(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_models_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.ListModelsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse()) + await client.list_models(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_models_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_models( + 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_models_flattened_error(): + client = ModelServiceClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_models_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_models( + 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_models_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + + +def test_list_models_pager(transport_name: str = "grpc"): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_models(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) + for i in results) +def test_list_models_pages(transport_name: str = "grpc"): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + pages = list(client.list_models(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_models_async_pager(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_models(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, model.Model) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_models_async_pages(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + 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_models(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", [ + model_service.UpdateModelRequest, + dict, +]) +def test_update_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_update_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.update_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + +@pytest.mark.asyncio +async def test_update_model_async(transport: str = 'grpc_asyncio', request_type=model_service.UpdateModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_update_model_async_from_dict(): + await test_update_model_async(request_type=dict) + + +def test_update_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.UpdateModelRequest() + + request.model.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + call.return_value = gcr_model.Model() + client.update_model(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', + 'model.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.UpdateModelRequest() + + request.model.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + await client.update_model(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', + 'model.name=name_value', + ) in kw['metadata'] + + +def test_update_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_model( + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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].model + mock_val = gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_model( + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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].model + mock_val = gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.TuneModelRequest, + dict, +]) +def test_tune_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.tune_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_tune_model_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 = ModelServiceClient( + 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.tune_model), + '__call__') as call: + client.tune_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + +@pytest.mark.asyncio +async def test_tune_model_async(transport: str = 'grpc_asyncio', request_type=model_service.TuneModelRequest): + client = ModelServiceAsyncClient( + 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.tune_model), + '__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.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_tune_model_async_from_dict(): + await test_tune_model_async(request_type=dict) + + +def test_tune_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.TuneModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.tune_model(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_tune_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.TuneModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.tune_model(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_tune_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__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.tune_model( + 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_tune_model_flattened_error(): + client = ModelServiceClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_tune_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__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.tune_model( + 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_tune_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.CreateModelRequest, + dict, +]) +def test_create_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["model"] = {'page_optimization_config': {'page_optimization_event_type': 'page_optimization_event_type_value', 'panels': [{'display_name': 'display_name_value', 'candidates': [{'serving_config_id': 'serving_config_id_value'}], 'default_candidate': {}}], 'restriction': 1}, 'name': 'name_value', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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.create_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_model_rest_required_fields(request_type=model_service.CreateModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dry_run", )) + 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 = ModelServiceClient( + 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.create_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(("dryRun", )) & set(("parent", "model", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_create_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_create_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.CreateModelRequest.pb(model_service.CreateModelRequest()) + 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 = model_service.CreateModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_model_rest_bad_request(transport: str = 'rest', request_type=model_service.CreateModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["model"] = {'page_optimization_config': {'page_optimization_event_type': 'page_optimization_event_type_value', 'panels': [{'display_name': 'display_name_value', 'candidates': [{'serving_config_id': 'serving_config_id_value'}], 'default_candidate': {}}], 'restriction': 1}, 'name': 'name_value', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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_model(request) + + +def test_create_model_rest_flattened(): + client = ModelServiceClient( + 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/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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.create_model(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/models" % client.transport._host, args[1]) + + +def test_create_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')), + ) + + +def test_create_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.GetModelRequest, + dict, +]) +def test_get_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_get_model_rest_required_fields(request_type=model_service.GetModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_get_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_get_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.GetModelRequest.pb(model_service.GetModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.GetModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.get_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_model_rest_bad_request(transport: str = 'rest', request_type=model_service.GetModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + +def test_get_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_model(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_get_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + + +def test_get_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.PauseModelRequest, + dict, +]) +def test_pause_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.pause_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_pause_model_rest_required_fields(request_type=model_service.PauseModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).pause_model._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()).pause_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.pause_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_pause_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.pause_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_pause_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_pause_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_pause_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.PauseModelRequest.pb(model_service.PauseModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.PauseModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.pause_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_pause_model_rest_bad_request(transport: str = 'rest', request_type=model_service.PauseModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.pause_model(request) + + +def test_pause_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.pause_model(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}:pause" % client.transport._host, args[1]) + + +def test_pause_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + + +def test_pause_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ResumeModelRequest, + dict, +]) +def test_resume_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.resume_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_resume_model_rest_required_fields(request_type=model_service.ResumeModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).resume_model._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()).resume_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.resume_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_resume_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.resume_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_resume_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_resume_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_resume_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ResumeModelRequest.pb(model_service.ResumeModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.ResumeModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.resume_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_resume_model_rest_bad_request(transport: str = 'rest', request_type=model_service.ResumeModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.resume_model(request) + + +def test_resume_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.resume_model(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}:resume" % client.transport._host, args[1]) + + +def test_resume_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + + +def test_resume_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.DeleteModelRequest, + dict, +]) +def test_delete_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_rest_required_fields(request_type=model_service.DeleteModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + 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_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "pre_delete_model") as pre: + pre.assert_not_called() + pb_message = model_service.DeleteModelRequest.pb(model_service.DeleteModelRequest()) + 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 = model_service.DeleteModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_model_rest_bad_request(transport: str = 'rest', request_type=model_service.DeleteModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + +def test_delete_model_rest_flattened(): + client = ModelServiceClient( + 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/catalogs/sample3/models/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_model(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_delete_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + + +def test_delete_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ListModelsRequest, + dict, +]) +def test_list_models_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = model_service.ListModelsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_models(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_models_rest_required_fields(request_type=model_service.ListModelsRequest): + transport_class = transports.ModelServiceRestTransport + + 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_models._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_models._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model_service.ListModelsResponse() + # 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 + + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_models(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_models_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_models._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_models_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_list_models") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_list_models") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ListModelsRequest.pb(model_service.ListModelsRequest()) + 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 = model_service.ListModelsResponse.to_json(model_service.ListModelsResponse()) + + request = model_service.ListModelsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model_service.ListModelsResponse() + + client.list_models(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_models_rest_bad_request(transport: str = 'rest', request_type=model_service.ListModelsRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_models(request) + + +def test_list_models_rest_flattened(): + client = ModelServiceClient( + 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 = model_service.ListModelsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_models(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/models" % client.transport._host, args[1]) + + +def test_list_models_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + + +def test_list_models_rest_pager(transport: str = 'rest'): + client = ModelServiceClient( + 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 = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(model_service.ListModelsResponse.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/catalogs/sample3'} + + pager = client.list_models(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) + for i in results) + + pages = list(client.list_models(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", [ + model_service.UpdateModelRequest, + dict, +]) +def test_update_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + request_init["model"] = {'page_optimization_config': {'page_optimization_event_type': 'page_optimization_event_type_value', 'panels': [{'display_name': 'display_name_value', 'candidates': [{'serving_config_id': 'serving_config_id_value'}], 'default_candidate': {}}], 'restriction': 1}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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 = gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_update_model_rest_required_fields(request_type=model_service.UpdateModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_model.Model() + # 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 + + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("model", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_update_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_update_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.UpdateModelRequest.pb(model_service.UpdateModelRequest()) + 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 = gcr_model.Model.to_json(gcr_model.Model()) + + request = model_service.UpdateModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_model.Model() + + client.update_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_model_rest_bad_request(transport: str = 'rest', request_type=model_service.UpdateModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + request_init["model"] = {'page_optimization_config': {'page_optimization_event_type': 'page_optimization_event_type_value', 'panels': [{'display_name': 'display_name_value', 'candidates': [{'serving_config_id': 'serving_config_id_value'}], 'default_candidate': {}}], 'restriction': 1}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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_model(request) + + +def test_update_model_rest_flattened(): + client = ModelServiceClient( + 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 = gcr_model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_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 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_model(**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/v2alpha/{model.name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_update_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(page_optimization_config=gcr_model.Model.PageOptimizationConfig(page_optimization_event_type='page_optimization_event_type_value')), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.TuneModelRequest, + dict, +]) +def test_tune_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = 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.tune_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_tune_model_rest_required_fields(request_type=model_service.TuneModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).tune_model._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()).tune_model._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 = ModelServiceClient( + 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.tune_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_tune_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.tune_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_tune_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_tune_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_tune_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.TuneModelRequest.pb(model_service.TuneModelRequest()) + 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 = model_service.TuneModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.tune_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_tune_model_rest_bad_request(transport: str = 'rest', request_type=model_service.TuneModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.tune_model(request) + + +def test_tune_model_rest_flattened(): + client = ModelServiceClient( + 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 = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.tune_model(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/models/*}:tune" % client.transport._host, args[1]) + + +def test_tune_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + + +def test_tune_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ModelServiceClient( + 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 = ModelServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ModelServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ModelServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, +]) +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 = ModelServiceClient.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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ModelServiceGrpcTransport, + ) + +def test_model_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_model_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.model_service.transports.ModelServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_model', + 'get_model', + 'pause_model', + 'resume_model', + 'delete_model', + 'list_models', + 'update_model', + 'tune_model', + 'get_operation', + 'list_operations', + ) + 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_model_service_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.retail_v2alpha.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_model_service_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.retail_v2alpha.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport() + adc.assert_called_once() + + +def test_model_service_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) + ModelServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + ], +) +def test_model_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, + ], +) +def test_model_service_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.ModelServiceGrpcTransport, grpc_helpers), + (transports.ModelServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_model_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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_model_service_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.ModelServiceRestTransport ( + 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_model_service_rest_lro_client(): + client = ModelServiceClient( + 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_model_service_host_no_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_model_service_host_with_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_model_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ModelServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ModelServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_model._session + session2 = client2.transport.create_model._session + assert session1 != session2 + session1 = client1.transport.get_model._session + session2 = client2.transport.get_model._session + assert session1 != session2 + session1 = client1.transport.pause_model._session + session2 = client2.transport.pause_model._session + assert session1 != session2 + session1 = client1.transport.resume_model._session + session2 = client2.transport.resume_model._session + assert session1 != session2 + session1 = client1.transport.delete_model._session + session2 = client2.transport.delete_model._session + assert session1 != session2 + session1 = client1.transport.list_models._session + session2 = client2.transport.list_models._session + assert session1 != session2 + session1 = client1.transport.update_model._session + session2 = client2.transport.update_model._session + assert session1 != session2 + session1 = client1.transport.tune_model._session + session2 = client2.transport.tune_model._session + assert session1 != session2 +def test_model_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcTransport( + 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_model_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcAsyncIOTransport( + 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.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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_model_service_grpc_lro_client(): + client = ModelServiceClient( + 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_model_service_grpc_lro_async_client(): + client = ModelServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ModelServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ModelServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_model_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + model = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format(project=project, location=location, catalog=catalog, model=model, ) + actual = ModelServiceClient.model_path(project, location, catalog, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "model": "clam", + } + path = ModelServiceClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_model_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ModelServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ModelServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ModelServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ModelServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ModelServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ModelServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ModelServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ModelServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ModelServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ModelServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.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.ModelServiceTransport, '_prep_wrapped_messages') as prep: + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ModelServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ModelServiceClient.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 = ModelServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ModelServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ModelServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ModelServiceClient( + 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 = ModelServiceClient( + 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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_prediction_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_prediction_service.py new file mode 100644 index 00000000..9cb3b690 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_prediction_service.py @@ -0,0 +1,1931 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.prediction_service import PredictionServiceAsyncClient +from google.cloud.retail_v2alpha.services.prediction_service import PredictionServiceClient +from google.cloud.retail_v2alpha.services.prediction_service import transports +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import prediction_service +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import promotion +from google.cloud.retail_v2alpha.types import user_event +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_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 PredictionServiceClient._get_default_mtls_endpoint(None) is None + assert PredictionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (PredictionServiceClient, "grpc"), + (PredictionServiceAsyncClient, "grpc_asyncio"), + (PredictionServiceClient, "rest"), +]) +def test_prediction_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.PredictionServiceGrpcTransport, "grpc"), + (transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.PredictionServiceRestTransport, "rest"), +]) +def test_prediction_service_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", [ + (PredictionServiceClient, "grpc"), + (PredictionServiceAsyncClient, "grpc_asyncio"), + (PredictionServiceClient, "rest"), +]) +def test_prediction_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_prediction_service_client_get_transport_class(): + transport = PredictionServiceClient.get_transport_class() + available_transports = [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceRestTransport, + ] + assert transport in available_transports + + transport = PredictionServiceClient.get_transport_class("grpc") + assert transport == transports.PredictionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_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(PredictionServiceClient, '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(PredictionServiceClient, '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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "true"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "false"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", "true"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_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", [ + PredictionServiceClient, PredictionServiceAsyncClient +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest"), +]) +def test_prediction_service_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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", grpc_helpers), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", None), +]) +def test_prediction_service_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_prediction_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.prediction_service.transports.PredictionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = PredictionServiceClient( + 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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", grpc_helpers), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_prediction_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + prediction_service.PredictRequest, + dict, +]) +def test_predict(request_type, transport: str = 'grpc'): + client = PredictionServiceClient( + 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + ) + response = client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +def test_predict_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 = PredictionServiceClient( + 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.predict), + '__call__') as call: + client.predict() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + +@pytest.mark.asyncio +async def test_predict_async(transport: str = 'grpc_asyncio', request_type=prediction_service.PredictRequest): + client = PredictionServiceAsyncClient( + 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + )) + response = await client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +@pytest.mark.asyncio +async def test_predict_async_from_dict(): + await test_predict_async(request_type=dict) + + +def test_predict_field_headers(): + client = PredictionServiceClient( + 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 = prediction_service.PredictRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = prediction_service.PredictResponse() + client.predict(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_predict_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = prediction_service.PredictRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse()) + await client.predict(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + prediction_service.PredictRequest, + dict, +]) +def test_predict_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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 = prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = prediction_service.PredictResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.predict(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +def test_predict_rest_required_fields(request_type=prediction_service.PredictRequest): + transport_class = transports.PredictionServiceRestTransport + + request_init = {} + request_init["placement"] = "" + 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()).predict._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["placement"] = 'placement_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).predict._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "placement" in jsonified_request + assert jsonified_request["placement"] == 'placement_value' + + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = prediction_service.PredictResponse() + # 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 + + pb_return_value = prediction_service.PredictResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.predict(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_predict_rest_unset_required_fields(): + transport = transports.PredictionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.predict._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("placement", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_predict_rest_interceptors(null_interceptor): + transport = transports.PredictionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PredictionServiceRestInterceptor(), + ) + client = PredictionServiceClient(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.PredictionServiceRestInterceptor, "post_predict") as post, \ + mock.patch.object(transports.PredictionServiceRestInterceptor, "pre_predict") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = prediction_service.PredictRequest.pb(prediction_service.PredictRequest()) + 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 = prediction_service.PredictResponse.to_json(prediction_service.PredictResponse()) + + request = prediction_service.PredictRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = prediction_service.PredictResponse() + + client.predict(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_predict_rest_bad_request(transport: str = 'rest', request_type=prediction_service.PredictRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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.predict(request) + + +def test_predict_rest_error(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PredictionServiceClient( + 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 = PredictionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PredictionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + transports.PredictionServiceRestTransport, +]) +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 = PredictionServiceClient.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 = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.PredictionServiceGrpcTransport, + ) + +def test_prediction_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_prediction_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.prediction_service.transports.PredictionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'predict', + 'get_operation', + 'list_operations', + ) + 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_prediction_service_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.retail_v2alpha.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_prediction_service_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.retail_v2alpha.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + +def test_prediction_service_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) + PredictionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_prediction_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + transports.PredictionServiceRestTransport, + ], +) +def test_prediction_service_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.PredictionServiceGrpcTransport, grpc_helpers), + (transports.PredictionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_prediction_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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_prediction_service_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.PredictionServiceRestTransport ( + 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_prediction_service_host_no_port(transport_name): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_prediction_service_host_with_port(transport_name): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_prediction_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = PredictionServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = PredictionServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.predict._session + session2 = client2.transport.predict._session + assert session1 != session2 +def test_prediction_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcTransport( + 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_prediction_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcAsyncIOTransport( + 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.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + product = "oyster" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = PredictionServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "catalog": "mussel", + "branch": "winkle", + "product": "nautilus", + } + path = PredictionServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = PredictionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = PredictionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = PredictionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = PredictionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = PredictionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = PredictionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = PredictionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = PredictionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = PredictionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = PredictionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.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.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = PredictionServiceClient.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 = PredictionServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = PredictionServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = PredictionServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = PredictionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = PredictionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = PredictionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = PredictionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = PredictionServiceClient( + 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 = PredictionServiceClient( + 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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_product_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_product_service.py new file mode 100644 index 00000000..3957ef29 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_product_service.py @@ -0,0 +1,7606 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.product_service import ProductServiceAsyncClient +from google.cloud.retail_v2alpha.services.product_service import ProductServiceClient +from google.cloud.retail_v2alpha.services.product_service import pagers +from google.cloud.retail_v2alpha.services.product_service import transports +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import product as gcr_product +from google.cloud.retail_v2alpha.types import product_service +from google.cloud.retail_v2alpha.types import promotion +from google.cloud.retail_v2alpha.types import purge_config +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.type import date_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 ProductServiceClient._get_default_mtls_endpoint(None) is None + assert ProductServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductServiceClient, "grpc"), + (ProductServiceAsyncClient, "grpc_asyncio"), + (ProductServiceClient, "rest"), +]) +def test_product_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ProductServiceGrpcTransport, "grpc"), + (transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ProductServiceRestTransport, "rest"), +]) +def test_product_service_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", [ + (ProductServiceClient, "grpc"), + (ProductServiceAsyncClient, "grpc_asyncio"), + (ProductServiceClient, "rest"), +]) +def test_product_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_product_service_client_get_transport_class(): + transport = ProductServiceClient.get_transport_class() + available_transports = [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceRestTransport, + ] + assert transport in available_transports + + transport = ProductServiceClient.get_transport_class("grpc") + assert transport == transports.ProductServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_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(ProductServiceClient, '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(ProductServiceClient, '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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "true"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "false"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", "true"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_product_service_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", [ + ProductServiceClient, ProductServiceAsyncClient +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest"), +]) +def test_product_service_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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", grpc_helpers), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", None), +]) +def test_product_service_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_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.product_service.transports.ProductServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ProductServiceClient( + 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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", grpc_helpers), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_product_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.CreateProductRequest, + dict, +]) +def test_create_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.CreateProductRequest() + +@pytest.mark.asyncio +async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_service.CreateProductRequest): + client = ProductServiceAsyncClient( + 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(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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 = gcr_product.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 = ProductServiceAsyncClient( + 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_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(gcr_product.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 = ProductServiceClient( + 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 = gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceAsyncClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.GetProductRequest, + dict, +]) +def test_get_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.GetProductRequest() + +@pytest.mark.asyncio +async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_service.GetProductRequest): + client = ProductServiceAsyncClient( + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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.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 = ProductServiceAsyncClient( + 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_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.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 = ProductServiceClient( + 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.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 = ProductServiceClient( + 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_service.GetProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_flattened_async(): + client = ProductServiceAsyncClient( + 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.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product.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 = ProductServiceAsyncClient( + 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_service.GetProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.ListProductsRequest, + dict, +]) +def test_list_products(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_service.ListProductsResponse( + next_page_token='next_page_token_value', + total_size=1086, + ) + 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_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' + assert response.total_size == 1086 + + +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 = ProductServiceClient( + 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_service.ListProductsRequest() + +@pytest.mark.asyncio +async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_service.ListProductsRequest): + client = ProductServiceAsyncClient( + 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_service.ListProductsResponse( + next_page_token='next_page_token_value', + total_size=1086, + )) + 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_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' + assert response.total_size == 1086 + + +@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 = ProductServiceClient( + 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_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_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 = ProductServiceAsyncClient( + 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_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_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 = ProductServiceClient( + 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_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 = ProductServiceClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_products_flattened_async(): + client = ProductServiceAsyncClient( + 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_service.ListProductsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_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 = ProductServiceAsyncClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_pager(transport_name: str = "grpc"): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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.Product) + for i in results) +def test_list_products_pages(transport_name: str = "grpc"): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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 = ProductServiceAsyncClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_async_pages(): + client = ProductServiceAsyncClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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_service.UpdateProductRequest, + dict, +]) +def test_update_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.UpdateProductRequest() + +@pytest.mark.asyncio +async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_service.UpdateProductRequest): + client = ProductServiceAsyncClient( + 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(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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 = gcr_product.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 = ProductServiceAsyncClient( + 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_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(gcr_product.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 = ProductServiceClient( + 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 = gcr_product.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceAsyncClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.DeleteProductRequest, + dict, +]) +def test_delete_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_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 = ProductServiceClient( + 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_service.DeleteProductRequest() + +@pytest.mark.asyncio +async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_service.DeleteProductRequest): + client = ProductServiceAsyncClient( + 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_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 = ProductServiceClient( + 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_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 = ProductServiceAsyncClient( + 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_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 = ProductServiceClient( + 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 = ProductServiceClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = ProductServiceAsyncClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeProductsRequest, + dict, +]) +def test_purge_products(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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] == purge_config.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 = ProductServiceClient( + 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] == purge_config.PurgeProductsRequest() + +@pytest.mark.asyncio +async def test_purge_products_async(transport: str = 'grpc_asyncio', request_type=purge_config.PurgeProductsRequest): + client = ProductServiceAsyncClient( + 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] == purge_config.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 = ProductServiceClient( + 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 = purge_config.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 = ProductServiceAsyncClient( + 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 = purge_config.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'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportProductsRequest, + dict, +]) +def test_import_products(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_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] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_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 = ProductServiceClient( + 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_products), + '__call__') as call: + client.import_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + +@pytest.mark.asyncio +async def test_import_products_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportProductsRequest): + client = ProductServiceAsyncClient( + 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_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.import_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_products_async_from_dict(): + await test_import_products_async(request_type=dict) + + +def test_import_products_field_headers(): + client = ProductServiceClient( + 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 = import_config.ImportProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_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_import_products_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = import_config.ImportProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_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'] + + +@pytest.mark.parametrize("request_type", [ + product_service.SetInventoryRequest, + dict, +]) +def test_set_inventory(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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.set_inventory), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.set_inventory(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_service.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_set_inventory_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 = ProductServiceClient( + 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.set_inventory), + '__call__') as call: + client.set_inventory() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.SetInventoryRequest() + +@pytest.mark.asyncio +async def test_set_inventory_async(transport: str = 'grpc_asyncio', request_type=product_service.SetInventoryRequest): + client = ProductServiceAsyncClient( + 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.set_inventory), + '__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.set_inventory(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_set_inventory_async_from_dict(): + await test_set_inventory_async(request_type=dict) + + +def test_set_inventory_field_headers(): + client = ProductServiceClient( + 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_service.SetInventoryRequest() + + request.inventory.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.set_inventory(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', + 'inventory.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_inventory_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.SetInventoryRequest() + + request.inventory.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.set_inventory(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', + 'inventory.name=name_value', + ) in kw['metadata'] + + +def test_set_inventory_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_set_inventory_flattened_error(): + client = ProductServiceClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_set_inventory_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_set_inventory_flattened_error_async(): + client = ProductServiceAsyncClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddFulfillmentPlacesRequest, + dict, +]) +def test_add_fulfillment_places(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.add_fulfillment_places(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_service.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_add_fulfillment_places_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 = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + client.add_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddFulfillmentPlacesRequest() + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.AddFulfillmentPlacesRequest): + client = ProductServiceAsyncClient( + 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_fulfillment_places), + '__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.add_fulfillment_places(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async_from_dict(): + await test_add_fulfillment_places_async(request_type=dict) + + +def test_add_fulfillment_places_field_headers(): + client = ProductServiceClient( + 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_service.AddFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.add_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.AddFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.add_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +def test_add_fulfillment_places_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__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.add_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_fulfillment_places_flattened_error(): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_fulfillment_places_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__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.add_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_fulfillment_places_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveFulfillmentPlacesRequest, + dict, +]) +def test_remove_fulfillment_places(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.remove_fulfillment_places(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_service.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_remove_fulfillment_places_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 = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + client.remove_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveFulfillmentPlacesRequest() + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveFulfillmentPlacesRequest): + client = ProductServiceAsyncClient( + 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_fulfillment_places), + '__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.remove_fulfillment_places(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async_from_dict(): + await test_remove_fulfillment_places_async(request_type=dict) + + +def test_remove_fulfillment_places_field_headers(): + client = ProductServiceClient( + 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_service.RemoveFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.remove_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.RemoveFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.remove_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +def test_remove_fulfillment_places_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__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.remove_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_fulfillment_places_flattened_error(): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__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.remove_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddLocalInventoriesRequest, + dict, +]) +def test_add_local_inventories(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.add_local_inventories(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_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_add_local_inventories_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 = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + client.add_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + +@pytest.mark.asyncio +async def test_add_local_inventories_async(transport: str = 'grpc_asyncio', request_type=product_service.AddLocalInventoriesRequest): + client = ProductServiceAsyncClient( + 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_local_inventories), + '__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.add_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_local_inventories_async_from_dict(): + await test_add_local_inventories_async(request_type=dict) + + +def test_add_local_inventories_field_headers(): + client = ProductServiceClient( + 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_service.AddLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.add_local_inventories(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.AddLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.add_local_inventories(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=product_value', + ) in kw['metadata'] + + +def test_add_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__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.add_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_local_inventories_flattened_error(): + client = ProductServiceClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__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.add_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveLocalInventoriesRequest, + dict, +]) +def test_remove_local_inventories(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.remove_local_inventories(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_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_remove_local_inventories_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 = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + client.remove_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + +@pytest.mark.asyncio +async def test_remove_local_inventories_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveLocalInventoriesRequest): + client = ProductServiceAsyncClient( + 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_local_inventories), + '__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.remove_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_local_inventories_async_from_dict(): + await test_remove_local_inventories_async(request_type=dict) + + +def test_remove_local_inventories_field_headers(): + client = ProductServiceClient( + 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_service.RemoveLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.remove_local_inventories(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.RemoveLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.remove_local_inventories(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=product_value', + ) in kw['metadata'] + + +def test_remove_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__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.remove_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_local_inventories_flattened_error(): + client = ProductServiceClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__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.remove_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.CreateProductRequest, + dict, +]) +def test_create_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_create_product_rest_required_fields(request_type=product_service.CreateProductRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["product_id"] = "" + 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 + assert "productId" not in jsonified_request + + 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 + assert "productId" in jsonified_request + assert jsonified_request["productId"] == request_init["product_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["productId"] = 'product_id_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' + assert "productId" in jsonified_request + assert jsonified_request["productId"] == 'product_id_value' + + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_product.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 + + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product(request) + + expected_params = [ + ( + "productId", + "", + ), + ('$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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productId", )) & set(("parent", "product", "productId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_create_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_create_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.CreateProductRequest.pb(product_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 = gcr_product.Product.to_json(gcr_product.Product()) + + request = product_service.CreateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_product.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_service.CreateProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = ProductServiceClient( + 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 = gcr_product.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2alpha/{parent=projects/*/locations/*/catalogs/*/branches/*}/products" % client.transport._host, args[1]) + + +def test_create_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +def test_create_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.GetProductRequest, + dict, +]) +def test_get_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_get_product_rest_required_fields(request_type=product_service.GetProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product.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 + + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(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.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_get_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_get_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.GetProductRequest.pb(product_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.Product.to_json(product.Product()) + + request = product_service.GetProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product.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_service.GetProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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 = ProductServiceClient( + 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.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # 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 + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_get_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.GetProductRequest(), + name='name_value', + ) + + +def test_get_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.ListProductsRequest, + dict, +]) +def test_list_products_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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_service.ListProductsResponse( + next_page_token='next_page_token_value', + total_size=1086, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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' + assert response.total_size == 1086 + + +def test_list_products_rest_required_fields(request_type=product_service.ListProductsRequest): + transport_class = transports.ProductServiceRestTransport + + 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(("filter", "page_size", "page_token", "read_mask", "require_total_size", )) + 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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_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 + + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", "readMask", "requireTotalSize", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_list_products") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_list_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.ListProductsRequest.pb(product_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_service.ListProductsResponse.to_json(product_service.ListProductsResponse()) + + request = product_service.ListProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_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_service.ListProductsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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.list_products(request) + + +def test_list_products_rest_flattened(): + client = ProductServiceClient( + 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_service.ListProductsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + + # 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 + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2alpha/{parent=projects/*/locations/*/catalogs/*/branches/*}/products" % client.transport._host, args[1]) + + +def test_list_products_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_rest_pager(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_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/catalogs/sample3/branches/sample4'} + + pager = client.list_products(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product.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_service.UpdateProductRequest, + dict, +]) +def test_update_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_update_product_rest_required_fields(request_type=product_service.UpdateProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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(("allow_missing", "update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_product.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 + + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("allowMissing", "updateMask", )) & set(("product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_update_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_update_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.UpdateProductRequest.pb(product_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 = gcr_product.Product.to_json(gcr_product.Product()) + + request = product_service.UpdateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_product.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_service.UpdateProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = ProductServiceClient( + 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 = gcr_product.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + + # get truthy value for each flattened field + mock_args = dict( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2alpha/{product.name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_update_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.DeleteProductRequest, + dict, +]) +def test_delete_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_service.DeleteProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("force", )) + 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 = ProductServiceClient( + 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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("force", )) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_product_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "pre_delete_product") as pre: + pre.assert_not_called() + pb_message = product_service.DeleteProductRequest.pb(product_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_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_service.DeleteProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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 = ProductServiceClient( + 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/catalogs/sample3/branches/sample4/products/sample5'} + + # 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/v2alpha/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_delete_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + + +def test_delete_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeProductsRequest, + dict, +]) +def test_purge_products_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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 = 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=purge_config.PurgeProductsRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["filter"] = "" + 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' + jsonified_request["filter"] = 'filter_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' + assert "filter" in jsonified_request + assert jsonified_request["filter"] == 'filter_value' + + client = ProductServiceClient( + 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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.purge_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "filter", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_purge_products_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_purge_products") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_purge_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = purge_config.PurgeProductsRequest.pb(purge_config.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 = purge_config.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=purge_config.PurgeProductsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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.purge_products(request) + + +def test_purge_products_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportProductsRequest, + dict, +]) +def test_import_products_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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 = 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_products(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_products_rest_required_fields(request_type=import_config.ImportProductsRequest): + transport_class = transports.ProductServiceRestTransport + + 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_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()).import_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 = ProductServiceClient( + 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_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_products_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_products_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_import_products") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_import_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportProductsRequest.pb(import_config.ImportProductsRequest()) + 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 = import_config.ImportProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_products_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportProductsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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.import_products(request) + + +def test_import_products_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.SetInventoryRequest, + dict, +]) +def test_set_inventory_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + 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.set_inventory(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_set_inventory_rest_required_fields(request_type=product_service.SetInventoryRequest): + transport_class = transports.ProductServiceRestTransport + + 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()).set_inventory._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()).set_inventory._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductServiceClient( + 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.set_inventory(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_set_inventory_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.set_inventory._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("inventory", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_inventory_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_set_inventory") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_set_inventory") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.SetInventoryRequest.pb(product_service.SetInventoryRequest()) + 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_service.SetInventoryRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.set_inventory(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_set_inventory_rest_bad_request(transport: str = 'rest', request_type=product_service.SetInventoryRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + 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.set_inventory(request) + + +def test_set_inventory_rest_flattened(): + client = ProductServiceClient( + 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 = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + + # get truthy value for each flattened field + mock_args = dict( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.set_inventory(**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/v2alpha/{inventory.name=projects/*/locations/*/catalogs/*/branches/*/products/**}:setInventory" % client.transport._host, args[1]) + + +def test_set_inventory_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_set_inventory_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddFulfillmentPlacesRequest, + dict, +]) +def test_add_fulfillment_places_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.add_fulfillment_places(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_add_fulfillment_places_rest_required_fields(request_type=product_service.AddFulfillmentPlacesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["type_"] = "" + request_init["place_ids"] = "" + 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_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["type"] = 'type__value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "type" in jsonified_request + assert jsonified_request["type"] == 'type__value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.add_fulfillment_places(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_fulfillment_places_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_fulfillment_places._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "type", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_fulfillment_places_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_add_fulfillment_places") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_add_fulfillment_places") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.AddFulfillmentPlacesRequest.pb(product_service.AddFulfillmentPlacesRequest()) + 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_service.AddFulfillmentPlacesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.add_fulfillment_places(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_fulfillment_places_rest_bad_request(transport: str = 'rest', request_type=product_service.AddFulfillmentPlacesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_fulfillment_places(request) + + +def test_add_fulfillment_places_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_fulfillment_places(**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/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addFulfillmentPlaces" % client.transport._host, args[1]) + + +def test_add_fulfillment_places_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +def test_add_fulfillment_places_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveFulfillmentPlacesRequest, + dict, +]) +def test_remove_fulfillment_places_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.remove_fulfillment_places(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_remove_fulfillment_places_rest_required_fields(request_type=product_service.RemoveFulfillmentPlacesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["type_"] = "" + request_init["place_ids"] = "" + 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_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["type"] = 'type__value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "type" in jsonified_request + assert jsonified_request["type"] == 'type__value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.remove_fulfillment_places(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_fulfillment_places_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_fulfillment_places._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "type", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_fulfillment_places_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_remove_fulfillment_places") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_remove_fulfillment_places") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.RemoveFulfillmentPlacesRequest.pb(product_service.RemoveFulfillmentPlacesRequest()) + 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_service.RemoveFulfillmentPlacesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.remove_fulfillment_places(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_fulfillment_places_rest_bad_request(transport: str = 'rest', request_type=product_service.RemoveFulfillmentPlacesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_fulfillment_places(request) + + +def test_remove_fulfillment_places_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_fulfillment_places(**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/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeFulfillmentPlaces" % client.transport._host, args[1]) + + +def test_remove_fulfillment_places_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + + +def test_remove_fulfillment_places_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddLocalInventoriesRequest, + dict, +]) +def test_add_local_inventories_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.add_local_inventories(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_add_local_inventories_rest_required_fields(request_type=product_service.AddLocalInventoriesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + 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_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductServiceClient( + 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.add_local_inventories(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_local_inventories_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_local_inventories._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "localInventories", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_local_inventories_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_add_local_inventories") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_add_local_inventories") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.AddLocalInventoriesRequest.pb(product_service.AddLocalInventoriesRequest()) + 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_service.AddLocalInventoriesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.add_local_inventories(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_local_inventories_rest_bad_request(transport: str = 'rest', request_type=product_service.AddLocalInventoriesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_local_inventories(request) + + +def test_add_local_inventories_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_local_inventories(**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/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addLocalInventories" % client.transport._host, args[1]) + + +def test_add_local_inventories_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + + +def test_add_local_inventories_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveLocalInventoriesRequest, + dict, +]) +def test_remove_local_inventories_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.remove_local_inventories(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_remove_local_inventories_rest_required_fields(request_type=product_service.RemoveLocalInventoriesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["place_ids"] = "" + 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_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.remove_local_inventories(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_local_inventories_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_local_inventories._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_local_inventories_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_remove_local_inventories") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_remove_local_inventories") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.RemoveLocalInventoriesRequest.pb(product_service.RemoveLocalInventoriesRequest()) + 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_service.RemoveLocalInventoriesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.remove_local_inventories(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_local_inventories_rest_bad_request(transport: str = 'rest', request_type=product_service.RemoveLocalInventoriesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_local_inventories(request) + + +def test_remove_local_inventories_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_local_inventories(**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/v2alpha/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeLocalInventories" % client.transport._host, args[1]) + + +def test_remove_local_inventories_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + + +def test_remove_local_inventories_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductServiceClient( + 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 = ProductServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + transports.ProductServiceRestTransport, +]) +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 = ProductServiceClient.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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ProductServiceGrpcTransport, + ) + +def test_product_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_product_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.product_service.transports.ProductServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_product', + 'get_product', + 'list_products', + 'update_product', + 'delete_product', + 'purge_products', + 'import_products', + 'set_inventory', + 'add_fulfillment_places', + 'remove_fulfillment_places', + 'add_local_inventories', + 'remove_local_inventories', + 'get_operation', + 'list_operations', + ) + 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_service_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.retail_v2alpha.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_product_service_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.retail_v2alpha.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport() + adc.assert_called_once() + + +def test_product_service_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) + ProductServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + ], +) +def test_product_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + transports.ProductServiceRestTransport, + ], +) +def test_product_service_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.ProductServiceGrpcTransport, grpc_helpers), + (transports.ProductServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_product_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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_service_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.ProductServiceRestTransport ( + 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_service_rest_lro_client(): + client = ProductServiceClient( + 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_service_host_no_port(transport_name): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_service_host_with_port(transport_name): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_product_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ProductServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ProductServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_product._session + session2 = client2.transport.create_product._session + assert session1 != session2 + session1 = client1.transport.get_product._session + session2 = client2.transport.get_product._session + assert session1 != session2 + session1 = client1.transport.list_products._session + session2 = client2.transport.list_products._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.purge_products._session + session2 = client2.transport.purge_products._session + assert session1 != session2 + session1 = client1.transport.import_products._session + session2 = client2.transport.import_products._session + assert session1 != session2 + session1 = client1.transport.set_inventory._session + session2 = client2.transport.set_inventory._session + assert session1 != session2 + session1 = client1.transport.add_fulfillment_places._session + session2 = client2.transport.add_fulfillment_places._session + assert session1 != session2 + session1 = client1.transport.remove_fulfillment_places._session + session2 = client2.transport.remove_fulfillment_places._session + assert session1 != session2 + session1 = client1.transport.add_local_inventories._session + session2 = client2.transport.add_local_inventories._session + assert session1 != session2 + session1 = client1.transport.remove_local_inventories._session + session2 = client2.transport.remove_local_inventories._session + assert session1 != session2 +def test_product_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcTransport( + 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_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcAsyncIOTransport( + 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.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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_service_grpc_lro_client(): + client = ProductServiceClient( + 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_service_grpc_lro_async_client(): + client = ProductServiceAsyncClient( + 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_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = ProductServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = ProductServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_branch_path(path) + assert expected == actual + +def test_product_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + branch = "abalone" + product = "squid" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = ProductServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "clam", + "location": "whelk", + "catalog": "octopus", + "branch": "oyster", + "product": "nudibranch", + } + path = ProductServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ProductServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ProductServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = ProductServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ProductServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ProductServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ProductServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = ProductServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ProductServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ProductServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ProductServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.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.ProductServiceTransport, '_prep_wrapped_messages') as prep: + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ProductServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ProductServiceClient.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 = ProductServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ProductServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ProductServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ProductServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ProductServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ProductServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ProductServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ProductServiceClient( + 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 = ProductServiceClient( + 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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_search_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_search_service.py new file mode 100644 index 00000000..07ec9081 --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_search_service.py @@ -0,0 +1,2263 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.search_service import SearchServiceAsyncClient +from google.cloud.retail_v2alpha.services.search_service import SearchServiceClient +from google.cloud.retail_v2alpha.services.search_service import pagers +from google.cloud.retail_v2alpha.services.search_service import transports +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +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 SearchServiceClient._get_default_mtls_endpoint(None) is None + assert SearchServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (SearchServiceClient, "grpc"), + (SearchServiceAsyncClient, "grpc_asyncio"), + (SearchServiceClient, "rest"), +]) +def test_search_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.SearchServiceGrpcTransport, "grpc"), + (transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.SearchServiceRestTransport, "rest"), +]) +def test_search_service_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", [ + (SearchServiceClient, "grpc"), + (SearchServiceAsyncClient, "grpc_asyncio"), + (SearchServiceClient, "rest"), +]) +def test_search_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_search_service_client_get_transport_class(): + transport = SearchServiceClient.get_transport_class() + available_transports = [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceRestTransport, + ] + assert transport in available_transports + + transport = SearchServiceClient.get_transport_class("grpc") + assert transport == transports.SearchServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_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(SearchServiceClient, '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(SearchServiceClient, '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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "true"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "false"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", "true"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_search_service_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", [ + SearchServiceClient, SearchServiceAsyncClient +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest"), +]) +def test_search_service_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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", grpc_helpers), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", None), +]) +def test_search_service_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_search_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.search_service.transports.SearchServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = SearchServiceClient( + 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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", grpc_helpers), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_search_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + search_service.SearchRequest, + dict, +]) +def test_search(request_type, transport: str = 'grpc'): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + ) + response = client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +def test_search_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 = SearchServiceClient( + 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.search), + '__call__') as call: + client.search() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + +@pytest.mark.asyncio +async def test_search_async(transport: str = 'grpc_asyncio', request_type=search_service.SearchRequest): + client = SearchServiceAsyncClient( + 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + )) + response = await client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAsyncPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +@pytest.mark.asyncio +async def test_search_async_from_dict(): + await test_search_async(request_type=dict) + + +def test_search_field_headers(): + client = SearchServiceClient( + 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 = search_service.SearchRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = search_service.SearchResponse() + client.search(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_search_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = search_service.SearchRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse()) + await client.search(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', + 'placement=placement_value', + ) in kw['metadata'] + + +def test_search_pager(transport_name: str = "grpc"): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('placement', ''), + )), + ) + pager = client.search(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in results) +def test_search_pages(transport_name: str = "grpc"): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + pages = list(client.search(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_search_async_pager(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + async_pager = await client.search(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, search_service.SearchResponse.SearchResult) + for i in responses) + + +@pytest.mark.asyncio +async def test_search_async_pages(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + 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.search(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", [ + search_service.SearchRequest, + dict, +]) +def test_search_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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 = search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = search_service.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.search(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +def test_search_rest_required_fields(request_type=search_service.SearchRequest): + transport_class = transports.SearchServiceRestTransport + + request_init = {} + request_init["placement"] = "" + request_init["visitor_id"] = "" + 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()).search._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["placement"] = 'placement_value' + jsonified_request["visitorId"] = 'visitor_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).search._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "placement" in jsonified_request + assert jsonified_request["placement"] == 'placement_value' + assert "visitorId" in jsonified_request + assert jsonified_request["visitorId"] == 'visitor_id_value' + + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = search_service.SearchResponse() + # 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 + + pb_return_value = search_service.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.search(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_search_rest_unset_required_fields(): + transport = transports.SearchServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.search._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("placement", "visitorId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_rest_interceptors(null_interceptor): + transport = transports.SearchServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.SearchServiceRestInterceptor(), + ) + client = SearchServiceClient(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.SearchServiceRestInterceptor, "post_search") as post, \ + mock.patch.object(transports.SearchServiceRestInterceptor, "pre_search") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) + 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 = search_service.SearchResponse.to_json(search_service.SearchResponse()) + + request = search_service.SearchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = search_service.SearchResponse() + + client.search(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_search_rest_bad_request(transport: str = 'rest', request_type=search_service.SearchRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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.search(request) + + +def test_search_rest_pager(transport: str = 'rest'): + client = SearchServiceClient( + 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 = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(search_service.SearchResponse.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 = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/sample4'} + + pager = client.search(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in results) + + pages = list(client.search(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SearchServiceClient( + 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 = SearchServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SearchServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SearchServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + transports.SearchServiceRestTransport, +]) +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 = SearchServiceClient.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 = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.SearchServiceGrpcTransport, + ) + +def test_search_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_search_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.search_service.transports.SearchServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'search', + 'get_operation', + 'list_operations', + ) + 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_search_service_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.retail_v2alpha.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_search_service_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.retail_v2alpha.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport() + adc.assert_called_once() + + +def test_search_service_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) + SearchServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + ], +) +def test_search_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + transports.SearchServiceRestTransport, + ], +) +def test_search_service_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.SearchServiceGrpcTransport, grpc_helpers), + (transports.SearchServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_search_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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_search_service_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.SearchServiceRestTransport ( + 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_search_service_host_no_port(transport_name): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_search_service_host_with_port(transport_name): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_search_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = SearchServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = SearchServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.search._session + session2 = client2.transport.search._session + assert session1 != session2 +def test_search_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcTransport( + 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_search_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcAsyncIOTransport( + 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.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = SearchServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = SearchServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_branch_path(path) + assert expected == actual + +def test_experiment_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + experiment = "abalone" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format(project=project, location=location, catalog=catalog, experiment=experiment, ) + actual = SearchServiceClient.experiment_path(project, location, catalog, experiment) + assert expected == actual + + +def test_parse_experiment_path(): + expected = { + "project": "squid", + "location": "clam", + "catalog": "whelk", + "experiment": "octopus", + } + path = SearchServiceClient.experiment_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_experiment_path(path) + assert expected == actual + +def test_product_path(): + project = "oyster" + location = "nudibranch" + catalog = "cuttlefish" + branch = "mussel" + product = "winkle" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = SearchServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "catalog": "abalone", + "branch": "squid", + "product": "clam", + } + path = SearchServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_product_path(path) + assert expected == actual + +def test_serving_config_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + serving_config = "nudibranch" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + actual = SearchServiceClient.serving_config_path(project, location, catalog, serving_config) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + "catalog": "winkle", + "serving_config": "nautilus", + } + path = SearchServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_serving_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = SearchServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = SearchServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = SearchServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = SearchServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = SearchServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = SearchServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = SearchServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = SearchServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = SearchServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = SearchServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.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.SearchServiceTransport, '_prep_wrapped_messages') as prep: + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.SearchServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = SearchServiceClient.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 = SearchServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = SearchServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = SearchServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = SearchServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = SearchServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = SearchServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = SearchServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = SearchServiceClient( + 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 = SearchServiceClient( + 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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_serving_config_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_serving_config_service.py new file mode 100644 index 00000000..b8a362ca --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_serving_config_service.py @@ -0,0 +1,5655 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.serving_config_service import ServingConfigServiceAsyncClient +from google.cloud.retail_v2alpha.services.serving_config_service import ServingConfigServiceClient +from google.cloud.retail_v2alpha.services.serving_config_service import pagers +from google.cloud.retail_v2alpha.services.serving_config_service import transports +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import search_service +from google.cloud.retail_v2alpha.types import serving_config +from google.cloud.retail_v2alpha.types import serving_config as gcr_serving_config +from google.cloud.retail_v2alpha.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_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 ServingConfigServiceClient._get_default_mtls_endpoint(None) is None + assert ServingConfigServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ServingConfigServiceClient, "grpc"), + (ServingConfigServiceAsyncClient, "grpc_asyncio"), + (ServingConfigServiceClient, "rest"), +]) +def test_serving_config_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ServingConfigServiceGrpcTransport, "grpc"), + (transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ServingConfigServiceRestTransport, "rest"), +]) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, "grpc"), + (ServingConfigServiceAsyncClient, "grpc_asyncio"), + (ServingConfigServiceClient, "rest"), +]) +def test_serving_config_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_serving_config_service_client_get_transport_class(): + transport = ServingConfigServiceClient.get_transport_class() + available_transports = [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceRestTransport, + ] + assert transport in available_transports + + transport = ServingConfigServiceClient.get_transport_class("grpc") + assert transport == transports.ServingConfigServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest"), +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +def test_serving_config_service_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(ServingConfigServiceClient, '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(ServingConfigServiceClient, '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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", "true"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", "false"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", "true"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_serving_config_service_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", [ + ServingConfigServiceClient, ServingConfigServiceAsyncClient +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest"), +]) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", grpc_helpers), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", None), +]) +def test_serving_config_service_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_serving_config_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.serving_config_service.transports.ServingConfigServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ServingConfigServiceClient( + 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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", grpc_helpers), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_serving_config_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.CreateServingConfigRequest, + dict, +]) +def test_create_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.create_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_create_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.create_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + +@pytest.mark.asyncio +async def test_create_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.CreateServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.create_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_create_serving_config_async_from_dict(): + await test_create_serving_config_async(request_type=dict) + + +def test_create_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.CreateServingConfigRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.create_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.CreateServingConfigRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.create_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_serving_config( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_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].serving_config + mock_val = gcr_serving_config.ServingConfig(name='name_value') + assert arg == mock_val + arg = args[0].serving_config_id + mock_val = 'serving_config_id_value' + assert arg == mock_val + + +def test_create_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + +@pytest.mark.asyncio +async def test_create_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_serving_config( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_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].serving_config + mock_val = gcr_serving_config.ServingConfig(name='name_value') + assert arg == mock_val + arg = args[0].serving_config_id + mock_val = 'serving_config_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.DeleteServingConfigRequest, + dict, +]) +def test_delete_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.delete_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + +@pytest.mark.asyncio +async def test_delete_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.DeleteServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_serving_config_async_from_dict(): + await test_delete_serving_config_async(request_type=dict) + + +def test_delete_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.DeleteServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__call__') as call: + call.return_value = None + client.delete_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.DeleteServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__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_serving_config( + 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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__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_serving_config( + 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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.UpdateServingConfigRequest, + dict, +]) +def test_update_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.update_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_update_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.update_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + +@pytest.mark.asyncio +async def test_update_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.UpdateServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.update_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_update_serving_config_async_from_dict(): + await test_update_serving_config_async(request_type=dict) + + +def test_update_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.UpdateServingConfigRequest() + + request.serving_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.update_serving_config(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', + 'serving_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.UpdateServingConfigRequest() + + request.serving_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.update_serving_config(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', + 'serving_config.name=name_value', + ) in kw['metadata'] + + +def test_update_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_serving_config( + serving_config=gcr_serving_config.ServingConfig(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].serving_config + mock_val = gcr_serving_config.ServingConfig(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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_serving_config( + serving_config=gcr_serving_config.ServingConfig(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].serving_config + mock_val = gcr_serving_config.ServingConfig(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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.GetServingConfigRequest, + dict, +]) +def test_get_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.get_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_get_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.get_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + +@pytest.mark.asyncio +async def test_get_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.GetServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.get_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_get_serving_config_async_from_dict(): + await test_get_serving_config_async(request_type=dict) + + +def test_get_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.GetServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + call.return_value = serving_config.ServingConfig() + client.get_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.GetServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig()) + await client.get_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_serving_config( + 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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_serving_config( + 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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.ListServingConfigsRequest, + dict, +]) +def test_list_serving_configs(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_serving_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_serving_configs_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 = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + client.list_serving_configs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + +@pytest.mark.asyncio +async def test_list_serving_configs_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.ListServingConfigsRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_serving_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_serving_configs_async_from_dict(): + await test_list_serving_configs_async(request_type=dict) + + +def test_list_serving_configs_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.ListServingConfigsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + call.return_value = serving_config_service.ListServingConfigsResponse() + client.list_serving_configs(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_serving_configs_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.ListServingConfigsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse()) + await client.list_serving_configs(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_serving_configs_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_serving_configs( + 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_serving_configs_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_serving_configs_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_serving_configs( + 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_serving_configs_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + + +def test_list_serving_configs_pager(transport_name: str = "grpc"): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_serving_configs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, serving_config.ServingConfig) + for i in results) +def test_list_serving_configs_pages(transport_name: str = "grpc"): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + pages = list(client.list_serving_configs(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_serving_configs_async_pager(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_serving_configs(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, serving_config.ServingConfig) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_serving_configs_async_pages(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + 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_serving_configs(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", [ + serving_config_service.AddControlRequest, + dict, +]) +def test_add_control(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.add_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_add_control_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 = ServingConfigServiceClient( + 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_control), + '__call__') as call: + client.add_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + +@pytest.mark.asyncio +async def test_add_control_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.AddControlRequest): + client = ServingConfigServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.add_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_add_control_async_from_dict(): + await test_add_control_async(request_type=dict) + + +def test_add_control_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.AddControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.add_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_control_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.AddControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.add_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +def test_add_control_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.add_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + + +def test_add_control_flattened_error(): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + +@pytest.mark.asyncio +async def test_add_control_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.add_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_control_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.RemoveControlRequest, + dict, +]) +def test_remove_control(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.remove_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_remove_control_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 = ServingConfigServiceClient( + 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_control), + '__call__') as call: + client.remove_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + +@pytest.mark.asyncio +async def test_remove_control_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.RemoveControlRequest): + client = ServingConfigServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.remove_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_remove_control_async_from_dict(): + await test_remove_control_async(request_type=dict) + + +def test_remove_control_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.RemoveControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.remove_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_control_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.RemoveControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.remove_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +def test_remove_control_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.remove_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + + +def test_remove_control_flattened_error(): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + +@pytest.mark.asyncio +async def test_remove_control_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.remove_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_control_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.CreateServingConfigRequest, + dict, +]) +def test_create_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["serving_config"] = {'name': 'name_value', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_create_serving_config_rest_required_fields(request_type=serving_config_service.CreateServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["serving_config_id"] = "" + 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 + assert "servingConfigId" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_serving_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "servingConfigId" in jsonified_request + assert jsonified_request["servingConfigId"] == request_init["serving_config_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["servingConfigId"] = 'serving_config_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_serving_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("serving_config_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' + assert "servingConfigId" in jsonified_request + assert jsonified_request["servingConfigId"] == 'serving_config_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_serving_config(request) + + expected_params = [ + ( + "servingConfigId", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("servingConfigId", )) & set(("parent", "servingConfig", "servingConfigId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_create_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_create_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.CreateServingConfigRequest.pb(serving_config_service.CreateServingConfigRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.CreateServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.create_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.CreateServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["serving_config"] = {'name': 'name_value', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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_serving_config(request) + + +def test_create_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_serving_config(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/servingConfigs" % client.transport._host, args[1]) + + +def test_create_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + + +def test_create_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.DeleteServingConfigRequest, + dict, +]) +def test_delete_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_serving_config_rest_required_fields(request_type=serving_config_service.DeleteServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + 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_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "pre_delete_serving_config") as pre: + pre.assert_not_called() + pb_message = serving_config_service.DeleteServingConfigRequest.pb(serving_config_service.DeleteServingConfigRequest()) + 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 = serving_config_service.DeleteServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.DeleteServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + +def test_delete_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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/catalogs/sample3/servingConfigs/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_serving_config(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_delete_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + + +def test_delete_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.UpdateServingConfigRequest, + dict, +]) +def test_update_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + request_init["serving_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_update_serving_config_rest_required_fields(request_type=serving_config_service.UpdateServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("servingConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_update_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_update_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.UpdateServingConfigRequest.pb(serving_config_service.UpdateServingConfigRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.UpdateServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.update_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.UpdateServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + request_init["serving_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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_serving_config(request) + + +def test_update_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + serving_config=gcr_serving_config.ServingConfig(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 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_serving_config(**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/v2alpha/{serving_config.name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_update_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.GetServingConfigRequest, + dict, +]) +def test_get_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_get_serving_config_rest_required_fields(request_type=serving_config_service.GetServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = serving_config.ServingConfig() + # 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 + + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_get_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_get_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.GetServingConfigRequest.pb(serving_config_service.GetServingConfigRequest()) + 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 = serving_config.ServingConfig.to_json(serving_config.ServingConfig()) + + request = serving_config_service.GetServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = serving_config.ServingConfig() + + client.get_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.GetServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + +def test_get_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_serving_config(**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/v2alpha/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_get_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + + +def test_get_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.ListServingConfigsRequest, + dict, +]) +def test_list_serving_configs_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_serving_configs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_serving_configs_rest_required_fields(request_type=serving_config_service.ListServingConfigsRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_configs._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_serving_configs._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = serving_config_service.ListServingConfigsResponse() + # 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 + + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_serving_configs(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_serving_configs_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_serving_configs._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_serving_configs_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_list_serving_configs") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_list_serving_configs") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.ListServingConfigsRequest.pb(serving_config_service.ListServingConfigsRequest()) + 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 = serving_config_service.ListServingConfigsResponse.to_json(serving_config_service.ListServingConfigsResponse()) + + request = serving_config_service.ListServingConfigsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = serving_config_service.ListServingConfigsResponse() + + client.list_serving_configs(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_serving_configs_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.ListServingConfigsRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_serving_configs(request) + + +def test_list_serving_configs_rest_flattened(): + client = ServingConfigServiceClient( + 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 = serving_config_service.ListServingConfigsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_serving_configs(**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/v2alpha/{parent=projects/*/locations/*/catalogs/*}/servingConfigs" % client.transport._host, args[1]) + + +def test_list_serving_configs_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + + +def test_list_serving_configs_rest_pager(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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 = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(serving_config_service.ListServingConfigsResponse.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/catalogs/sample3'} + + pager = client.list_serving_configs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, serving_config.ServingConfig) + for i in results) + + pages = list(client.list_serving_configs(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", [ + serving_config_service.AddControlRequest, + dict, +]) +def test_add_control_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_add_control_rest_required_fields(request_type=serving_config_service.AddControlRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["serving_config"] = "" + request_init["control_id"] = "" + 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_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["servingConfig"] = 'serving_config_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "servingConfig" in jsonified_request + assert jsonified_request["servingConfig"] == 'serving_config_value' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_control_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("servingConfig", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_control_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_add_control") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_add_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.AddControlRequest.pb(serving_config_service.AddControlRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.AddControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.add_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_control_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.AddControlRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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.add_control(request) + + +def test_add_control_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + serving_config='serving_config_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_control(**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/v2alpha/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:addControl" % client.transport._host, args[1]) + + +def test_add_control_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + + +def test_add_control_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.RemoveControlRequest, + dict, +]) +def test_remove_control_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_remove_control_rest_required_fields(request_type=serving_config_service.RemoveControlRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["serving_config"] = "" + request_init["control_id"] = "" + 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_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["servingConfig"] = 'serving_config_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "servingConfig" in jsonified_request + assert jsonified_request["servingConfig"] == 'serving_config_value' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_control_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("servingConfig", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_control_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_remove_control") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_remove_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.RemoveControlRequest.pb(serving_config_service.RemoveControlRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.RemoveControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.remove_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_control_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.RemoveControlRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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.remove_control(request) + + +def test_remove_control_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + serving_config='serving_config_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_control(**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/v2alpha/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:removeControl" % client.transport._host, args[1]) + + +def test_remove_control_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + + +def test_remove_control_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + 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 = ServingConfigServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ServingConfigServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ServingConfigServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + transports.ServingConfigServiceRestTransport, +]) +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 = ServingConfigServiceClient.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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ServingConfigServiceGrpcTransport, + ) + +def test_serving_config_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ServingConfigServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_serving_config_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.serving_config_service.transports.ServingConfigServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ServingConfigServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_serving_config', + 'delete_serving_config', + 'update_serving_config', + 'get_serving_config', + 'list_serving_configs', + 'add_control', + 'remove_control', + 'get_operation', + 'list_operations', + ) + 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_serving_config_service_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.retail_v2alpha.services.serving_config_service.transports.ServingConfigServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServingConfigServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_serving_config_service_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.retail_v2alpha.services.serving_config_service.transports.ServingConfigServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServingConfigServiceTransport() + adc.assert_called_once() + + +def test_serving_config_service_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) + ServingConfigServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + ], +) +def test_serving_config_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + transports.ServingConfigServiceRestTransport, + ], +) +def test_serving_config_service_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.ServingConfigServiceGrpcTransport, grpc_helpers), + (transports.ServingConfigServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_serving_config_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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_serving_config_service_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.ServingConfigServiceRestTransport ( + 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_serving_config_service_host_no_port(transport_name): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_serving_config_service_host_with_port(transport_name): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_serving_config_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ServingConfigServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ServingConfigServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_serving_config._session + session2 = client2.transport.create_serving_config._session + assert session1 != session2 + session1 = client1.transport.delete_serving_config._session + session2 = client2.transport.delete_serving_config._session + assert session1 != session2 + session1 = client1.transport.update_serving_config._session + session2 = client2.transport.update_serving_config._session + assert session1 != session2 + session1 = client1.transport.get_serving_config._session + session2 = client2.transport.get_serving_config._session + assert session1 != session2 + session1 = client1.transport.list_serving_configs._session + session2 = client2.transport.list_serving_configs._session + assert session1 != session2 + session1 = client1.transport.add_control._session + session2 = client2.transport.add_control._session + assert session1 != session2 + session1 = client1.transport.remove_control._session + session2 = client2.transport.remove_control._session + assert session1 != session2 +def test_serving_config_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ServingConfigServiceGrpcTransport( + 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_serving_config_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ServingConfigServiceGrpcAsyncIOTransport( + 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.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ServingConfigServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ServingConfigServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_serving_config_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + serving_config = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + actual = ServingConfigServiceClient.serving_config_path(project, location, catalog, serving_config) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "serving_config": "clam", + } + path = ServingConfigServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_serving_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ServingConfigServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ServingConfigServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ServingConfigServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ServingConfigServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ServingConfigServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ServingConfigServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ServingConfigServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ServingConfigServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ServingConfigServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ServingConfigServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.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.ServingConfigServiceTransport, '_prep_wrapped_messages') as prep: + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ServingConfigServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ServingConfigServiceClient.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 = ServingConfigServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ServingConfigServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ServingConfigServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ServingConfigServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ServingConfigServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ServingConfigServiceClient( + 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 = ServingConfigServiceClient( + 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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport), +]) +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/v2alpha/tests/unit/gapic/retail_v2alpha/test_user_event_service.py b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_user_event_service.py new file mode 100644 index 00000000..0c41cc6c --- /dev/null +++ b/owl-bot-staging/v2alpha/tests/unit/gapic/retail_v2alpha/test_user_event_service.py @@ -0,0 +1,3431 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 import httpbody_pb2 # type: ignore +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.location import locations_pb2 +from google.cloud.retail_v2alpha.services.user_event_service import UserEventServiceAsyncClient +from google.cloud.retail_v2alpha.services.user_event_service import UserEventServiceClient +from google.cloud.retail_v2alpha.services.user_event_service import transports +from google.cloud.retail_v2alpha.types import common +from google.cloud.retail_v2alpha.types import import_config +from google.cloud.retail_v2alpha.types import product +from google.cloud.retail_v2alpha.types import promotion +from google.cloud.retail_v2alpha.types import purge_config +from google.cloud.retail_v2alpha.types import user_event +from google.cloud.retail_v2alpha.types import user_event_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 duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.type import date_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 UserEventServiceClient._get_default_mtls_endpoint(None) is None + assert UserEventServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (UserEventServiceClient, "grpc"), + (UserEventServiceAsyncClient, "grpc_asyncio"), + (UserEventServiceClient, "rest"), +]) +def test_user_event_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.UserEventServiceGrpcTransport, "grpc"), + (transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.UserEventServiceRestTransport, "rest"), +]) +def test_user_event_service_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", [ + (UserEventServiceClient, "grpc"), + (UserEventServiceAsyncClient, "grpc_asyncio"), + (UserEventServiceClient, "rest"), +]) +def test_user_event_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_user_event_service_client_get_transport_class(): + transport = UserEventServiceClient.get_transport_class() + available_transports = [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceRestTransport, + ] + assert transport in available_transports + + transport = UserEventServiceClient.get_transport_class("grpc") + assert transport == transports.UserEventServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_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(UserEventServiceClient, '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(UserEventServiceClient, '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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "true"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "false"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", "true"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_user_event_service_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", [ + UserEventServiceClient, UserEventServiceAsyncClient +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest"), +]) +def test_user_event_service_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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", grpc_helpers), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", None), +]) +def test_user_event_service_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_user_event_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2alpha.services.user_event_service.transports.UserEventServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = UserEventServiceClient( + 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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", grpc_helpers), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_user_event_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.WriteUserEventRequest, + dict, +]) +def test_write_user_event(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + ) + response = client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +def test_write_user_event_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 = UserEventServiceClient( + 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.write_user_event), + '__call__') as call: + client.write_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + +@pytest.mark.asyncio +async def test_write_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.WriteUserEventRequest): + client = UserEventServiceAsyncClient( + 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + )) + response = await client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +@pytest.mark.asyncio +async def test_write_user_event_async_from_dict(): + await test_write_user_event_async(request_type=dict) + + +def test_write_user_event_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.WriteUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = user_event.UserEvent() + client.write_user_event(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_write_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.WriteUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent()) + await client.write_user_event(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.CollectUserEventRequest, + dict, +]) +def test_collect_user_event(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.collect_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + ) + response = client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +def test_collect_user_event_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 = UserEventServiceClient( + 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.collect_user_event), + '__call__') as call: + client.collect_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + +@pytest.mark.asyncio +async def test_collect_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.CollectUserEventRequest): + client = UserEventServiceAsyncClient( + 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.collect_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + )) + response = await client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +@pytest.mark.asyncio +async def test_collect_user_event_async_from_dict(): + await test_collect_user_event_async(request_type=dict) + + +def test_collect_user_event_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.CollectUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = httpbody_pb2.HttpBody() + client.collect_user_event(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_collect_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.CollectUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody()) + await client.collect_user_event(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'] + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeUserEventsRequest, + dict, +]) +def test_purge_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.purge_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_purge_user_events_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 = UserEventServiceClient( + 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_user_events), + '__call__') as call: + client.purge_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + +@pytest.mark.asyncio +async def test_purge_user_events_async(transport: str = 'grpc_asyncio', request_type=purge_config.PurgeUserEventsRequest): + client = UserEventServiceAsyncClient( + 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_user_events), + '__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_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_purge_user_events_async_from_dict(): + await test_purge_user_events_async(request_type=dict) + + +def test_purge_user_events_field_headers(): + client = UserEventServiceClient( + 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 = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.purge_user_events(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_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.purge_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportUserEventsRequest, + dict, +]) +def test_import_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_user_events_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 = UserEventServiceClient( + 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_user_events), + '__call__') as call: + client.import_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + +@pytest.mark.asyncio +async def test_import_user_events_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportUserEventsRequest): + client = UserEventServiceAsyncClient( + 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_user_events), + '__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_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_user_events_async_from_dict(): + await test_import_user_events_async(request_type=dict) + + +def test_import_user_events_field_headers(): + client = UserEventServiceClient( + 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 = import_config.ImportUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_user_events(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_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = import_config.ImportUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.RejoinUserEventsRequest, + dict, +]) +def test_rejoin_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.rejoin_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_rejoin_user_events_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 = UserEventServiceClient( + 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.rejoin_user_events), + '__call__') as call: + client.rejoin_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + +@pytest.mark.asyncio +async def test_rejoin_user_events_async(transport: str = 'grpc_asyncio', request_type=user_event_service.RejoinUserEventsRequest): + client = UserEventServiceAsyncClient( + 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.rejoin_user_events), + '__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.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_rejoin_user_events_async_from_dict(): + await test_rejoin_user_events_async(request_type=dict) + + +def test_rejoin_user_events_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.rejoin_user_events(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_rejoin_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.rejoin_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.WriteUserEventRequest, + dict, +]) +def test_write_user_event_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["user_event"] = {'event_type': 'event_type_value', 'visitor_id': 'visitor_id_value', 'session_id': 'session_id_value', 'event_time': {'seconds': 751, 'nanos': 543}, 'experiment_ids': ['experiment_ids_value1', 'experiment_ids_value2'], 'attribution_token': 'attribution_token_value', 'product_details': [{'product': {'expire_time': {}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]}, 'quantity': {}}], 'completion_detail': {'completion_attribution_token': 'completion_attribution_token_value', 'selected_suggestion': 'selected_suggestion_value', 'selected_position': 1821}, 'attributes': {}, 'cart_id': 'cart_id_value', 'purchase_transaction': {'id': 'id_value', 'revenue': 0.762, 'tax': 0.333, 'cost': 0.441, 'currency_code': 'currency_code_value'}, 'search_query': 'search_query_value', 'filter': 'filter_value', 'order_by': 'order_by_value', 'offset': 647, 'page_categories': ['page_categories_value1', 'page_categories_value2'], 'user_info': {'user_id': 'user_id_value', 'ip_address': 'ip_address_value', 'user_agent': 'user_agent_value', 'direct_user_request': True}, 'uri': 'uri_value', 'referrer_uri': 'referrer_uri_value', 'page_view_id': 'page_view_id_value', 'entity': 'entity_value'} + 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 = user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = user_event.UserEvent.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.write_user_event(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +def test_write_user_event_rest_required_fields(request_type=user_event_service.WriteUserEventRequest): + transport_class = transports.UserEventServiceRestTransport + + 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()).write_user_event._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()).write_user_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("write_async", )) + 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 = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = user_event.UserEvent() + # 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 + + pb_return_value = user_event.UserEvent.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.write_user_event(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_write_user_event_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.write_user_event._get_unset_required_fields({}) + assert set(unset_fields) == (set(("writeAsync", )) & set(("parent", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_write_user_event_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_write_user_event") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_write_user_event") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.WriteUserEventRequest.pb(user_event_service.WriteUserEventRequest()) + 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 = user_event.UserEvent.to_json(user_event.UserEvent()) + + request = user_event_service.WriteUserEventRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = user_event.UserEvent() + + client.write_user_event(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_write_user_event_rest_bad_request(transport: str = 'rest', request_type=user_event_service.WriteUserEventRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["user_event"] = {'event_type': 'event_type_value', 'visitor_id': 'visitor_id_value', 'session_id': 'session_id_value', 'event_time': {'seconds': 751, 'nanos': 543}, 'experiment_ids': ['experiment_ids_value1', 'experiment_ids_value2'], 'attribution_token': 'attribution_token_value', 'product_details': [{'product': {'expire_time': {}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]}, 'quantity': {}}], 'completion_detail': {'completion_attribution_token': 'completion_attribution_token_value', 'selected_suggestion': 'selected_suggestion_value', 'selected_position': 1821}, 'attributes': {}, 'cart_id': 'cart_id_value', 'purchase_transaction': {'id': 'id_value', 'revenue': 0.762, 'tax': 0.333, 'cost': 0.441, 'currency_code': 'currency_code_value'}, 'search_query': 'search_query_value', 'filter': 'filter_value', 'order_by': 'order_by_value', 'offset': 647, 'page_categories': ['page_categories_value1', 'page_categories_value2'], 'user_info': {'user_id': 'user_id_value', 'ip_address': 'ip_address_value', 'user_agent': 'user_agent_value', 'direct_user_request': True}, 'uri': 'uri_value', 'referrer_uri': 'referrer_uri_value', 'page_view_id': 'page_view_id_value', 'entity': 'entity_value'} + 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.write_user_event(request) + + +def test_write_user_event_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.CollectUserEventRequest, + dict, +]) +def test_collect_user_event_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.collect_user_event(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +def test_collect_user_event_rest_required_fields(request_type=user_event_service.CollectUserEventRequest): + transport_class = transports.UserEventServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["user_event"] = "" + 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 + assert "userEvent" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).collect_user_event._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "userEvent" in jsonified_request + assert jsonified_request["userEvent"] == request_init["user_event"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["userEvent"] = 'user_event_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).collect_user_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("ets", "prebuilt_rule", "raw_json", "uri", "user_event", )) + 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' + assert "userEvent" in jsonified_request + assert jsonified_request["userEvent"] == 'user_event_value' + + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = httpbody_pb2.HttpBody() + # 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 + + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.collect_user_event(request) + + expected_params = [ + ( + "userEvent", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_collect_user_event_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.collect_user_event._get_unset_required_fields({}) + assert set(unset_fields) == (set(("ets", "prebuiltRule", "rawJson", "uri", "userEvent", )) & set(("parent", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_collect_user_event_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_collect_user_event") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_collect_user_event") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.CollectUserEventRequest.pb(user_event_service.CollectUserEventRequest()) + 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(httpbody_pb2.HttpBody()) + + request = user_event_service.CollectUserEventRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = httpbody_pb2.HttpBody() + + client.collect_user_event(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_collect_user_event_rest_bad_request(transport: str = 'rest', request_type=user_event_service.CollectUserEventRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.collect_user_event(request) + + +def test_collect_user_event_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeUserEventsRequest, + dict, +]) +def test_purge_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_purge_user_events_rest_required_fields(request_type=purge_config.PurgeUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["filter"] = "" + 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_user_events._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' + jsonified_request["filter"] = 'filter_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).purge_user_events._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' + assert "filter" in jsonified_request + assert jsonified_request["filter"] == 'filter_value' + + client = UserEventServiceClient( + 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_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_purge_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.purge_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "filter", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_purge_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_purge_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_purge_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = purge_config.PurgeUserEventsRequest.pb(purge_config.PurgeUserEventsRequest()) + 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 = purge_config.PurgeUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.purge_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_purge_user_events_rest_bad_request(transport: str = 'rest', request_type=purge_config.PurgeUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.purge_user_events(request) + + +def test_purge_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportUserEventsRequest, + dict, +]) +def test_import_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_user_events_rest_required_fields(request_type=import_config.ImportUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + 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_user_events._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_user_events._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 = UserEventServiceClient( + 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_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_import_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_import_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportUserEventsRequest.pb(import_config.ImportUserEventsRequest()) + 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 = import_config.ImportUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_user_events_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.import_user_events(request) + + +def test_import_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.RejoinUserEventsRequest, + dict, +]) +def test_rejoin_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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.rejoin_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_rejoin_user_events_rest_required_fields(request_type=user_event_service.RejoinUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + 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()).rejoin_user_events._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()).rejoin_user_events._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 = UserEventServiceClient( + 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.rejoin_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_rejoin_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.rejoin_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_rejoin_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_rejoin_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_rejoin_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.RejoinUserEventsRequest.pb(user_event_service.RejoinUserEventsRequest()) + 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 = user_event_service.RejoinUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.rejoin_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_rejoin_user_events_rest_bad_request(transport: str = 'rest', request_type=user_event_service.RejoinUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.rejoin_user_events(request) + + +def test_rejoin_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserEventServiceClient( + 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 = UserEventServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = UserEventServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.UserEventServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + transports.UserEventServiceRestTransport, +]) +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 = UserEventServiceClient.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 = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.UserEventServiceGrpcTransport, + ) + +def test_user_event_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_user_event_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2alpha.services.user_event_service.transports.UserEventServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'write_user_event', + 'collect_user_event', + 'purge_user_events', + 'import_user_events', + 'rejoin_user_events', + 'get_operation', + 'list_operations', + ) + 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_user_event_service_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.retail_v2alpha.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_user_event_service_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.retail_v2alpha.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport() + adc.assert_called_once() + + +def test_user_event_service_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) + UserEventServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + ], +) +def test_user_event_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + transports.UserEventServiceRestTransport, + ], +) +def test_user_event_service_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.UserEventServiceGrpcTransport, grpc_helpers), + (transports.UserEventServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_user_event_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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_user_event_service_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.UserEventServiceRestTransport ( + 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_user_event_service_rest_lro_client(): + client = UserEventServiceClient( + 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_user_event_service_host_no_port(transport_name): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_user_event_service_host_with_port(transport_name): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_user_event_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = UserEventServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = UserEventServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.write_user_event._session + session2 = client2.transport.write_user_event._session + assert session1 != session2 + session1 = client1.transport.collect_user_event._session + session2 = client2.transport.collect_user_event._session + assert session1 != session2 + session1 = client1.transport.purge_user_events._session + session2 = client2.transport.purge_user_events._session + assert session1 != session2 + session1 = client1.transport.import_user_events._session + session2 = client2.transport.import_user_events._session + assert session1 != session2 + session1 = client1.transport.rejoin_user_events._session + session2 = client2.transport.rejoin_user_events._session + assert session1 != session2 +def test_user_event_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcTransport( + 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_user_event_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcAsyncIOTransport( + 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.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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_user_event_service_grpc_lro_client(): + client = UserEventServiceClient( + 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_user_event_service_grpc_lro_async_client(): + client = UserEventServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = UserEventServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = UserEventServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_product_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + branch = "nautilus" + product = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = UserEventServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + "branch": "whelk", + "product": "octopus", + } + path = UserEventServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = UserEventServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = UserEventServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format(folder=folder, ) + actual = UserEventServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = UserEventServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format(organization=organization, ) + actual = UserEventServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = UserEventServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format(project=project, ) + actual = UserEventServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = UserEventServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "squid" + location = "clam" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = UserEventServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = UserEventServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.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.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = UserEventServiceClient.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 = UserEventServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = UserEventServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = UserEventServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = UserEventServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = UserEventServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = UserEventServiceClient( + 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 = UserEventServiceClient( + 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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport), +]) +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/v2beta/.coveragerc b/owl-bot-staging/v2beta/.coveragerc new file mode 100644 index 00000000..3d15c56d --- /dev/null +++ b/owl-bot-staging/v2beta/.coveragerc @@ -0,0 +1,13 @@ +[run] +branch = True + +[report] +show_missing = True +omit = + google/cloud/retail/__init__.py + google/cloud/retail/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/v2beta/.flake8 b/owl-bot-staging/v2beta/.flake8 new file mode 100644 index 00000000..29227d4c --- /dev/null +++ b/owl-bot-staging/v2beta/.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/v2beta/MANIFEST.in b/owl-bot-staging/v2beta/MANIFEST.in new file mode 100644 index 00000000..43074617 --- /dev/null +++ b/owl-bot-staging/v2beta/MANIFEST.in @@ -0,0 +1,2 @@ +recursive-include google/cloud/retail *.py +recursive-include google/cloud/retail_v2beta *.py diff --git a/owl-bot-staging/v2beta/README.rst b/owl-bot-staging/v2beta/README.rst new file mode 100644 index 00000000..cb039760 --- /dev/null +++ b/owl-bot-staging/v2beta/README.rst @@ -0,0 +1,49 @@ +Python Client for Google Cloud Retail 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 Retail 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/v2beta/docs/_static/custom.css b/owl-bot-staging/v2beta/docs/_static/custom.css new file mode 100644 index 00000000..06423be0 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/_static/custom.css @@ -0,0 +1,3 @@ +dl.field-list > dt { + min-width: 100px +} diff --git a/owl-bot-staging/v2beta/docs/conf.py b/owl-bot-staging/v2beta/docs/conf.py new file mode 100644 index 00000000..995e6a64 --- /dev/null +++ b/owl-bot-staging/v2beta/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-retail 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-retail" +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-retail-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-retail.tex", + u"google-cloud-retail 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-retail", + u"Google Cloud Retail 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-retail", + u"google-cloud-retail Documentation", + author, + "google-cloud-retail", + "GAPIC library for Google Cloud Retail 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/v2beta/docs/index.rst b/owl-bot-staging/v2beta/docs/index.rst new file mode 100644 index 00000000..fd60fc85 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/index.rst @@ -0,0 +1,7 @@ +API Reference +------------- +.. toctree:: + :maxdepth: 2 + + retail_v2beta/services + retail_v2beta/types diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/catalog_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/catalog_service.rst new file mode 100644 index 00000000..3a7c19e6 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/catalog_service.rst @@ -0,0 +1,10 @@ +CatalogService +-------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.catalog_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2beta.services.catalog_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/completion_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/completion_service.rst new file mode 100644 index 00000000..1f6782ed --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/completion_service.rst @@ -0,0 +1,6 @@ +CompletionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.completion_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/control_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/control_service.rst new file mode 100644 index 00000000..86cfcba1 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/control_service.rst @@ -0,0 +1,10 @@ +ControlService +-------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.control_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2beta.services.control_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/model_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/model_service.rst new file mode 100644 index 00000000..eaa3b059 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/model_service.rst @@ -0,0 +1,10 @@ +ModelService +------------------------------ + +.. automodule:: google.cloud.retail_v2beta.services.model_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2beta.services.model_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/prediction_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/prediction_service.rst new file mode 100644 index 00000000..903c951d --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/prediction_service.rst @@ -0,0 +1,6 @@ +PredictionService +----------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.prediction_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/product_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/product_service.rst new file mode 100644 index 00000000..489daa22 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/product_service.rst @@ -0,0 +1,10 @@ +ProductService +-------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.product_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2beta.services.product_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/search_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/search_service.rst new file mode 100644 index 00000000..591f5c86 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/search_service.rst @@ -0,0 +1,10 @@ +SearchService +------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.search_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2beta.services.search_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/services.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/services.rst new file mode 100644 index 00000000..970cae46 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/services.rst @@ -0,0 +1,14 @@ +Services for Google Cloud Retail v2beta API +=========================================== +.. toctree:: + :maxdepth: 2 + + catalog_service + completion_service + control_service + model_service + prediction_service + product_service + search_service + serving_config_service + user_event_service diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/serving_config_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/serving_config_service.rst new file mode 100644 index 00000000..c074749c --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/serving_config_service.rst @@ -0,0 +1,10 @@ +ServingConfigService +-------------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.serving_config_service + :members: + :inherited-members: + +.. automodule:: google.cloud.retail_v2beta.services.serving_config_service.pagers + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/types.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/types.rst new file mode 100644 index 00000000..00c6f0b6 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/types.rst @@ -0,0 +1,6 @@ +Types for Google Cloud Retail v2beta API +======================================== + +.. automodule:: google.cloud.retail_v2beta.types + :members: + :show-inheritance: diff --git a/owl-bot-staging/v2beta/docs/retail_v2beta/user_event_service.rst b/owl-bot-staging/v2beta/docs/retail_v2beta/user_event_service.rst new file mode 100644 index 00000000..11ab3794 --- /dev/null +++ b/owl-bot-staging/v2beta/docs/retail_v2beta/user_event_service.rst @@ -0,0 +1,6 @@ +UserEventService +---------------------------------- + +.. automodule:: google.cloud.retail_v2beta.services.user_event_service + :members: + :inherited-members: diff --git a/owl-bot-staging/v2beta/google/cloud/retail/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail/__init__.py new file mode 100644 index 00000000..52ccbe94 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail/__init__.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail import gapic_version as package_version + +__version__ = package_version.__version__ + + +from google.cloud.retail_v2beta.services.catalog_service.client import CatalogServiceClient +from google.cloud.retail_v2beta.services.catalog_service.async_client import CatalogServiceAsyncClient +from google.cloud.retail_v2beta.services.completion_service.client import CompletionServiceClient +from google.cloud.retail_v2beta.services.completion_service.async_client import CompletionServiceAsyncClient +from google.cloud.retail_v2beta.services.control_service.client import ControlServiceClient +from google.cloud.retail_v2beta.services.control_service.async_client import ControlServiceAsyncClient +from google.cloud.retail_v2beta.services.model_service.client import ModelServiceClient +from google.cloud.retail_v2beta.services.model_service.async_client import ModelServiceAsyncClient +from google.cloud.retail_v2beta.services.prediction_service.client import PredictionServiceClient +from google.cloud.retail_v2beta.services.prediction_service.async_client import PredictionServiceAsyncClient +from google.cloud.retail_v2beta.services.product_service.client import ProductServiceClient +from google.cloud.retail_v2beta.services.product_service.async_client import ProductServiceAsyncClient +from google.cloud.retail_v2beta.services.search_service.client import SearchServiceClient +from google.cloud.retail_v2beta.services.search_service.async_client import SearchServiceAsyncClient +from google.cloud.retail_v2beta.services.serving_config_service.client import ServingConfigServiceClient +from google.cloud.retail_v2beta.services.serving_config_service.async_client import ServingConfigServiceAsyncClient +from google.cloud.retail_v2beta.services.user_event_service.client import UserEventServiceClient +from google.cloud.retail_v2beta.services.user_event_service.async_client import UserEventServiceAsyncClient + +from google.cloud.retail_v2beta.types.catalog import AttributesConfig +from google.cloud.retail_v2beta.types.catalog import Catalog +from google.cloud.retail_v2beta.types.catalog import CatalogAttribute +from google.cloud.retail_v2beta.types.catalog import CompletionConfig +from google.cloud.retail_v2beta.types.catalog import MerchantCenterFeedFilter +from google.cloud.retail_v2beta.types.catalog import MerchantCenterLink +from google.cloud.retail_v2beta.types.catalog import MerchantCenterLinkingConfig +from google.cloud.retail_v2beta.types.catalog import ProductLevelConfig +from google.cloud.retail_v2beta.types.catalog_service import AddCatalogAttributeRequest +from google.cloud.retail_v2beta.types.catalog_service import BatchRemoveCatalogAttributesRequest +from google.cloud.retail_v2beta.types.catalog_service import BatchRemoveCatalogAttributesResponse +from google.cloud.retail_v2beta.types.catalog_service import GetAttributesConfigRequest +from google.cloud.retail_v2beta.types.catalog_service import GetCompletionConfigRequest +from google.cloud.retail_v2beta.types.catalog_service import GetDefaultBranchRequest +from google.cloud.retail_v2beta.types.catalog_service import GetDefaultBranchResponse +from google.cloud.retail_v2beta.types.catalog_service import ListCatalogsRequest +from google.cloud.retail_v2beta.types.catalog_service import ListCatalogsResponse +from google.cloud.retail_v2beta.types.catalog_service import RemoveCatalogAttributeRequest +from google.cloud.retail_v2beta.types.catalog_service import ReplaceCatalogAttributeRequest +from google.cloud.retail_v2beta.types.catalog_service import SetDefaultBranchRequest +from google.cloud.retail_v2beta.types.catalog_service import UpdateAttributesConfigRequest +from google.cloud.retail_v2beta.types.catalog_service import UpdateCatalogRequest +from google.cloud.retail_v2beta.types.catalog_service import UpdateCompletionConfigRequest +from google.cloud.retail_v2beta.types.common import Audience +from google.cloud.retail_v2beta.types.common import ColorInfo +from google.cloud.retail_v2beta.types.common import Condition +from google.cloud.retail_v2beta.types.common import CustomAttribute +from google.cloud.retail_v2beta.types.common import FulfillmentInfo +from google.cloud.retail_v2beta.types.common import Image +from google.cloud.retail_v2beta.types.common import Interval +from google.cloud.retail_v2beta.types.common import LocalInventory +from google.cloud.retail_v2beta.types.common import PriceInfo +from google.cloud.retail_v2beta.types.common import Rating +from google.cloud.retail_v2beta.types.common import Rule +from google.cloud.retail_v2beta.types.common import UserInfo +from google.cloud.retail_v2beta.types.common import AttributeConfigLevel +from google.cloud.retail_v2beta.types.common import RecommendationsFilteringOption +from google.cloud.retail_v2beta.types.common import SearchSolutionUseCase +from google.cloud.retail_v2beta.types.common import SolutionType +from google.cloud.retail_v2beta.types.completion_service import CompleteQueryRequest +from google.cloud.retail_v2beta.types.completion_service import CompleteQueryResponse +from google.cloud.retail_v2beta.types.control import Control +from google.cloud.retail_v2beta.types.control_service import CreateControlRequest +from google.cloud.retail_v2beta.types.control_service import DeleteControlRequest +from google.cloud.retail_v2beta.types.control_service import GetControlRequest +from google.cloud.retail_v2beta.types.control_service import ListControlsRequest +from google.cloud.retail_v2beta.types.control_service import ListControlsResponse +from google.cloud.retail_v2beta.types.control_service import UpdateControlRequest +from google.cloud.retail_v2beta.types.export_config import BigQueryOutputResult +from google.cloud.retail_v2beta.types.export_config import ExportErrorsConfig +from google.cloud.retail_v2beta.types.export_config import ExportMetadata +from google.cloud.retail_v2beta.types.export_config import ExportProductsResponse +from google.cloud.retail_v2beta.types.export_config import ExportUserEventsResponse +from google.cloud.retail_v2beta.types.export_config import GcsOutputResult +from google.cloud.retail_v2beta.types.export_config import OutputResult +from google.cloud.retail_v2beta.types.import_config import BigQuerySource +from google.cloud.retail_v2beta.types.import_config import CompletionDataInputConfig +from google.cloud.retail_v2beta.types.import_config import GcsSource +from google.cloud.retail_v2beta.types.import_config import ImportCompletionDataRequest +from google.cloud.retail_v2beta.types.import_config import ImportCompletionDataResponse +from google.cloud.retail_v2beta.types.import_config import ImportErrorsConfig +from google.cloud.retail_v2beta.types.import_config import ImportMetadata +from google.cloud.retail_v2beta.types.import_config import ImportProductsRequest +from google.cloud.retail_v2beta.types.import_config import ImportProductsResponse +from google.cloud.retail_v2beta.types.import_config import ImportUserEventsRequest +from google.cloud.retail_v2beta.types.import_config import ImportUserEventsResponse +from google.cloud.retail_v2beta.types.import_config import ProductInlineSource +from google.cloud.retail_v2beta.types.import_config import ProductInputConfig +from google.cloud.retail_v2beta.types.import_config import UserEventImportSummary +from google.cloud.retail_v2beta.types.import_config import UserEventInlineSource +from google.cloud.retail_v2beta.types.import_config import UserEventInputConfig +from google.cloud.retail_v2beta.types.model import Model +from google.cloud.retail_v2beta.types.model_service import CreateModelMetadata +from google.cloud.retail_v2beta.types.model_service import CreateModelRequest +from google.cloud.retail_v2beta.types.model_service import DeleteModelRequest +from google.cloud.retail_v2beta.types.model_service import GetModelRequest +from google.cloud.retail_v2beta.types.model_service import ListModelsRequest +from google.cloud.retail_v2beta.types.model_service import ListModelsResponse +from google.cloud.retail_v2beta.types.model_service import PauseModelRequest +from google.cloud.retail_v2beta.types.model_service import ResumeModelRequest +from google.cloud.retail_v2beta.types.model_service import TuneModelMetadata +from google.cloud.retail_v2beta.types.model_service import TuneModelRequest +from google.cloud.retail_v2beta.types.model_service import TuneModelResponse +from google.cloud.retail_v2beta.types.model_service import UpdateModelRequest +from google.cloud.retail_v2beta.types.prediction_service import PredictRequest +from google.cloud.retail_v2beta.types.prediction_service import PredictResponse +from google.cloud.retail_v2beta.types.product import Product +from google.cloud.retail_v2beta.types.product_service import AddFulfillmentPlacesMetadata +from google.cloud.retail_v2beta.types.product_service import AddFulfillmentPlacesRequest +from google.cloud.retail_v2beta.types.product_service import AddFulfillmentPlacesResponse +from google.cloud.retail_v2beta.types.product_service import AddLocalInventoriesMetadata +from google.cloud.retail_v2beta.types.product_service import AddLocalInventoriesRequest +from google.cloud.retail_v2beta.types.product_service import AddLocalInventoriesResponse +from google.cloud.retail_v2beta.types.product_service import CreateProductRequest +from google.cloud.retail_v2beta.types.product_service import DeleteProductRequest +from google.cloud.retail_v2beta.types.product_service import GetProductRequest +from google.cloud.retail_v2beta.types.product_service import ListProductsRequest +from google.cloud.retail_v2beta.types.product_service import ListProductsResponse +from google.cloud.retail_v2beta.types.product_service import RemoveFulfillmentPlacesMetadata +from google.cloud.retail_v2beta.types.product_service import RemoveFulfillmentPlacesRequest +from google.cloud.retail_v2beta.types.product_service import RemoveFulfillmentPlacesResponse +from google.cloud.retail_v2beta.types.product_service import RemoveLocalInventoriesMetadata +from google.cloud.retail_v2beta.types.product_service import RemoveLocalInventoriesRequest +from google.cloud.retail_v2beta.types.product_service import RemoveLocalInventoriesResponse +from google.cloud.retail_v2beta.types.product_service import SetInventoryMetadata +from google.cloud.retail_v2beta.types.product_service import SetInventoryRequest +from google.cloud.retail_v2beta.types.product_service import SetInventoryResponse +from google.cloud.retail_v2beta.types.product_service import UpdateProductRequest +from google.cloud.retail_v2beta.types.promotion import Promotion +from google.cloud.retail_v2beta.types.purge_config import PurgeMetadata +from google.cloud.retail_v2beta.types.purge_config import PurgeUserEventsRequest +from google.cloud.retail_v2beta.types.purge_config import PurgeUserEventsResponse +from google.cloud.retail_v2beta.types.search_service import ExperimentInfo +from google.cloud.retail_v2beta.types.search_service import SearchRequest +from google.cloud.retail_v2beta.types.search_service import SearchResponse +from google.cloud.retail_v2beta.types.serving_config import ServingConfig +from google.cloud.retail_v2beta.types.serving_config_service import AddControlRequest +from google.cloud.retail_v2beta.types.serving_config_service import CreateServingConfigRequest +from google.cloud.retail_v2beta.types.serving_config_service import DeleteServingConfigRequest +from google.cloud.retail_v2beta.types.serving_config_service import GetServingConfigRequest +from google.cloud.retail_v2beta.types.serving_config_service import ListServingConfigsRequest +from google.cloud.retail_v2beta.types.serving_config_service import ListServingConfigsResponse +from google.cloud.retail_v2beta.types.serving_config_service import RemoveControlRequest +from google.cloud.retail_v2beta.types.serving_config_service import UpdateServingConfigRequest +from google.cloud.retail_v2beta.types.user_event import CompletionDetail +from google.cloud.retail_v2beta.types.user_event import ProductDetail +from google.cloud.retail_v2beta.types.user_event import PurchaseTransaction +from google.cloud.retail_v2beta.types.user_event import UserEvent +from google.cloud.retail_v2beta.types.user_event_service import CollectUserEventRequest +from google.cloud.retail_v2beta.types.user_event_service import RejoinUserEventsMetadata +from google.cloud.retail_v2beta.types.user_event_service import RejoinUserEventsRequest +from google.cloud.retail_v2beta.types.user_event_service import RejoinUserEventsResponse +from google.cloud.retail_v2beta.types.user_event_service import WriteUserEventRequest + +__all__ = ('CatalogServiceClient', + 'CatalogServiceAsyncClient', + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', + 'ControlServiceClient', + 'ControlServiceAsyncClient', + 'ModelServiceClient', + 'ModelServiceAsyncClient', + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', + 'ProductServiceClient', + 'ProductServiceAsyncClient', + 'SearchServiceClient', + 'SearchServiceAsyncClient', + 'ServingConfigServiceClient', + 'ServingConfigServiceAsyncClient', + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', + 'AttributesConfig', + 'Catalog', + 'CatalogAttribute', + 'CompletionConfig', + 'MerchantCenterFeedFilter', + 'MerchantCenterLink', + 'MerchantCenterLinkingConfig', + 'ProductLevelConfig', + 'AddCatalogAttributeRequest', + 'BatchRemoveCatalogAttributesRequest', + 'BatchRemoveCatalogAttributesResponse', + 'GetAttributesConfigRequest', + 'GetCompletionConfigRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'RemoveCatalogAttributeRequest', + 'ReplaceCatalogAttributeRequest', + 'SetDefaultBranchRequest', + 'UpdateAttributesConfigRequest', + 'UpdateCatalogRequest', + 'UpdateCompletionConfigRequest', + 'Audience', + 'ColorInfo', + 'Condition', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'LocalInventory', + 'PriceInfo', + 'Rating', + 'Rule', + 'UserInfo', + 'AttributeConfigLevel', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'SolutionType', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'Control', + 'CreateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + 'UpdateControlRequest', + 'BigQueryOutputResult', + 'ExportErrorsConfig', + 'ExportMetadata', + 'ExportProductsResponse', + 'ExportUserEventsResponse', + 'GcsOutputResult', + 'OutputResult', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'Model', + 'CreateModelMetadata', + 'CreateModelRequest', + 'DeleteModelRequest', + 'GetModelRequest', + 'ListModelsRequest', + 'ListModelsResponse', + 'PauseModelRequest', + 'ResumeModelRequest', + 'TuneModelMetadata', + 'TuneModelRequest', + 'TuneModelResponse', + 'UpdateModelRequest', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'Promotion', + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'ExperimentInfo', + 'SearchRequest', + 'SearchResponse', + 'ServingConfig', + 'AddControlRequest', + 'CreateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'RemoveControlRequest', + 'UpdateServingConfigRequest', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail/gapic_version.py b/owl-bot-staging/v2beta/google/cloud/retail/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail/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/v2beta/google/cloud/retail/py.typed b/owl-bot-staging/v2beta/google/cloud/retail/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/__init__.py new file mode 100644 index 00000000..c95bf9ce --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/__init__.py @@ -0,0 +1,326 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta import gapic_version as package_version + +__version__ = package_version.__version__ + + +from .services.catalog_service import CatalogServiceClient +from .services.catalog_service import CatalogServiceAsyncClient +from .services.completion_service import CompletionServiceClient +from .services.completion_service import CompletionServiceAsyncClient +from .services.control_service import ControlServiceClient +from .services.control_service import ControlServiceAsyncClient +from .services.model_service import ModelServiceClient +from .services.model_service import ModelServiceAsyncClient +from .services.prediction_service import PredictionServiceClient +from .services.prediction_service import PredictionServiceAsyncClient +from .services.product_service import ProductServiceClient +from .services.product_service import ProductServiceAsyncClient +from .services.search_service import SearchServiceClient +from .services.search_service import SearchServiceAsyncClient +from .services.serving_config_service import ServingConfigServiceClient +from .services.serving_config_service import ServingConfigServiceAsyncClient +from .services.user_event_service import UserEventServiceClient +from .services.user_event_service import UserEventServiceAsyncClient + +from .types.catalog import AttributesConfig +from .types.catalog import Catalog +from .types.catalog import CatalogAttribute +from .types.catalog import CompletionConfig +from .types.catalog import MerchantCenterFeedFilter +from .types.catalog import MerchantCenterLink +from .types.catalog import MerchantCenterLinkingConfig +from .types.catalog import ProductLevelConfig +from .types.catalog_service import AddCatalogAttributeRequest +from .types.catalog_service import BatchRemoveCatalogAttributesRequest +from .types.catalog_service import BatchRemoveCatalogAttributesResponse +from .types.catalog_service import GetAttributesConfigRequest +from .types.catalog_service import GetCompletionConfigRequest +from .types.catalog_service import GetDefaultBranchRequest +from .types.catalog_service import GetDefaultBranchResponse +from .types.catalog_service import ListCatalogsRequest +from .types.catalog_service import ListCatalogsResponse +from .types.catalog_service import RemoveCatalogAttributeRequest +from .types.catalog_service import ReplaceCatalogAttributeRequest +from .types.catalog_service import SetDefaultBranchRequest +from .types.catalog_service import UpdateAttributesConfigRequest +from .types.catalog_service import UpdateCatalogRequest +from .types.catalog_service import UpdateCompletionConfigRequest +from .types.common import Audience +from .types.common import ColorInfo +from .types.common import Condition +from .types.common import CustomAttribute +from .types.common import FulfillmentInfo +from .types.common import Image +from .types.common import Interval +from .types.common import LocalInventory +from .types.common import PriceInfo +from .types.common import Rating +from .types.common import Rule +from .types.common import UserInfo +from .types.common import AttributeConfigLevel +from .types.common import RecommendationsFilteringOption +from .types.common import SearchSolutionUseCase +from .types.common import SolutionType +from .types.completion_service import CompleteQueryRequest +from .types.completion_service import CompleteQueryResponse +from .types.control import Control +from .types.control_service import CreateControlRequest +from .types.control_service import DeleteControlRequest +from .types.control_service import GetControlRequest +from .types.control_service import ListControlsRequest +from .types.control_service import ListControlsResponse +from .types.control_service import UpdateControlRequest +from .types.export_config import BigQueryOutputResult +from .types.export_config import ExportErrorsConfig +from .types.export_config import ExportMetadata +from .types.export_config import ExportProductsResponse +from .types.export_config import ExportUserEventsResponse +from .types.export_config import GcsOutputResult +from .types.export_config import OutputResult +from .types.import_config import BigQuerySource +from .types.import_config import CompletionDataInputConfig +from .types.import_config import GcsSource +from .types.import_config import ImportCompletionDataRequest +from .types.import_config import ImportCompletionDataResponse +from .types.import_config import ImportErrorsConfig +from .types.import_config import ImportMetadata +from .types.import_config import ImportProductsRequest +from .types.import_config import ImportProductsResponse +from .types.import_config import ImportUserEventsRequest +from .types.import_config import ImportUserEventsResponse +from .types.import_config import ProductInlineSource +from .types.import_config import ProductInputConfig +from .types.import_config import UserEventImportSummary +from .types.import_config import UserEventInlineSource +from .types.import_config import UserEventInputConfig +from .types.model import Model +from .types.model_service import CreateModelMetadata +from .types.model_service import CreateModelRequest +from .types.model_service import DeleteModelRequest +from .types.model_service import GetModelRequest +from .types.model_service import ListModelsRequest +from .types.model_service import ListModelsResponse +from .types.model_service import PauseModelRequest +from .types.model_service import ResumeModelRequest +from .types.model_service import TuneModelMetadata +from .types.model_service import TuneModelRequest +from .types.model_service import TuneModelResponse +from .types.model_service import UpdateModelRequest +from .types.prediction_service import PredictRequest +from .types.prediction_service import PredictResponse +from .types.product import Product +from .types.product_service import AddFulfillmentPlacesMetadata +from .types.product_service import AddFulfillmentPlacesRequest +from .types.product_service import AddFulfillmentPlacesResponse +from .types.product_service import AddLocalInventoriesMetadata +from .types.product_service import AddLocalInventoriesRequest +from .types.product_service import AddLocalInventoriesResponse +from .types.product_service import CreateProductRequest +from .types.product_service import DeleteProductRequest +from .types.product_service import GetProductRequest +from .types.product_service import ListProductsRequest +from .types.product_service import ListProductsResponse +from .types.product_service import RemoveFulfillmentPlacesMetadata +from .types.product_service import RemoveFulfillmentPlacesRequest +from .types.product_service import RemoveFulfillmentPlacesResponse +from .types.product_service import RemoveLocalInventoriesMetadata +from .types.product_service import RemoveLocalInventoriesRequest +from .types.product_service import RemoveLocalInventoriesResponse +from .types.product_service import SetInventoryMetadata +from .types.product_service import SetInventoryRequest +from .types.product_service import SetInventoryResponse +from .types.product_service import UpdateProductRequest +from .types.promotion import Promotion +from .types.purge_config import PurgeMetadata +from .types.purge_config import PurgeUserEventsRequest +from .types.purge_config import PurgeUserEventsResponse +from .types.search_service import ExperimentInfo +from .types.search_service import SearchRequest +from .types.search_service import SearchResponse +from .types.serving_config import ServingConfig +from .types.serving_config_service import AddControlRequest +from .types.serving_config_service import CreateServingConfigRequest +from .types.serving_config_service import DeleteServingConfigRequest +from .types.serving_config_service import GetServingConfigRequest +from .types.serving_config_service import ListServingConfigsRequest +from .types.serving_config_service import ListServingConfigsResponse +from .types.serving_config_service import RemoveControlRequest +from .types.serving_config_service import UpdateServingConfigRequest +from .types.user_event import CompletionDetail +from .types.user_event import ProductDetail +from .types.user_event import PurchaseTransaction +from .types.user_event import UserEvent +from .types.user_event_service import CollectUserEventRequest +from .types.user_event_service import RejoinUserEventsMetadata +from .types.user_event_service import RejoinUserEventsRequest +from .types.user_event_service import RejoinUserEventsResponse +from .types.user_event_service import WriteUserEventRequest + +__all__ = ( + 'CatalogServiceAsyncClient', + 'CompletionServiceAsyncClient', + 'ControlServiceAsyncClient', + 'ModelServiceAsyncClient', + 'PredictionServiceAsyncClient', + 'ProductServiceAsyncClient', + 'SearchServiceAsyncClient', + 'ServingConfigServiceAsyncClient', + 'UserEventServiceAsyncClient', +'AddCatalogAttributeRequest', +'AddControlRequest', +'AddFulfillmentPlacesMetadata', +'AddFulfillmentPlacesRequest', +'AddFulfillmentPlacesResponse', +'AddLocalInventoriesMetadata', +'AddLocalInventoriesRequest', +'AddLocalInventoriesResponse', +'AttributeConfigLevel', +'AttributesConfig', +'Audience', +'BatchRemoveCatalogAttributesRequest', +'BatchRemoveCatalogAttributesResponse', +'BigQueryOutputResult', +'BigQuerySource', +'Catalog', +'CatalogAttribute', +'CatalogServiceClient', +'CollectUserEventRequest', +'ColorInfo', +'CompleteQueryRequest', +'CompleteQueryResponse', +'CompletionConfig', +'CompletionDataInputConfig', +'CompletionDetail', +'CompletionServiceClient', +'Condition', +'Control', +'ControlServiceClient', +'CreateControlRequest', +'CreateModelMetadata', +'CreateModelRequest', +'CreateProductRequest', +'CreateServingConfigRequest', +'CustomAttribute', +'DeleteControlRequest', +'DeleteModelRequest', +'DeleteProductRequest', +'DeleteServingConfigRequest', +'ExperimentInfo', +'ExportErrorsConfig', +'ExportMetadata', +'ExportProductsResponse', +'ExportUserEventsResponse', +'FulfillmentInfo', +'GcsOutputResult', +'GcsSource', +'GetAttributesConfigRequest', +'GetCompletionConfigRequest', +'GetControlRequest', +'GetDefaultBranchRequest', +'GetDefaultBranchResponse', +'GetModelRequest', +'GetProductRequest', +'GetServingConfigRequest', +'Image', +'ImportCompletionDataRequest', +'ImportCompletionDataResponse', +'ImportErrorsConfig', +'ImportMetadata', +'ImportProductsRequest', +'ImportProductsResponse', +'ImportUserEventsRequest', +'ImportUserEventsResponse', +'Interval', +'ListCatalogsRequest', +'ListCatalogsResponse', +'ListControlsRequest', +'ListControlsResponse', +'ListModelsRequest', +'ListModelsResponse', +'ListProductsRequest', +'ListProductsResponse', +'ListServingConfigsRequest', +'ListServingConfigsResponse', +'LocalInventory', +'MerchantCenterFeedFilter', +'MerchantCenterLink', +'MerchantCenterLinkingConfig', +'Model', +'ModelServiceClient', +'OutputResult', +'PauseModelRequest', +'PredictRequest', +'PredictResponse', +'PredictionServiceClient', +'PriceInfo', +'Product', +'ProductDetail', +'ProductInlineSource', +'ProductInputConfig', +'ProductLevelConfig', +'ProductServiceClient', +'Promotion', +'PurchaseTransaction', +'PurgeMetadata', +'PurgeUserEventsRequest', +'PurgeUserEventsResponse', +'Rating', +'RecommendationsFilteringOption', +'RejoinUserEventsMetadata', +'RejoinUserEventsRequest', +'RejoinUserEventsResponse', +'RemoveCatalogAttributeRequest', +'RemoveControlRequest', +'RemoveFulfillmentPlacesMetadata', +'RemoveFulfillmentPlacesRequest', +'RemoveFulfillmentPlacesResponse', +'RemoveLocalInventoriesMetadata', +'RemoveLocalInventoriesRequest', +'RemoveLocalInventoriesResponse', +'ReplaceCatalogAttributeRequest', +'ResumeModelRequest', +'Rule', +'SearchRequest', +'SearchResponse', +'SearchServiceClient', +'SearchSolutionUseCase', +'ServingConfig', +'ServingConfigServiceClient', +'SetDefaultBranchRequest', +'SetInventoryMetadata', +'SetInventoryRequest', +'SetInventoryResponse', +'SolutionType', +'TuneModelMetadata', +'TuneModelRequest', +'TuneModelResponse', +'UpdateAttributesConfigRequest', +'UpdateCatalogRequest', +'UpdateCompletionConfigRequest', +'UpdateControlRequest', +'UpdateModelRequest', +'UpdateProductRequest', +'UpdateServingConfigRequest', +'UserEvent', +'UserEventImportSummary', +'UserEventInlineSource', +'UserEventInputConfig', +'UserEventServiceClient', +'UserInfo', +'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/gapic_metadata.json b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/gapic_metadata.json new file mode 100644 index 00000000..65789002 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/gapic_metadata.json @@ -0,0 +1,960 @@ + { + "comment": "This file maps proto services/RPCs to the corresponding library clients/methods", + "language": "python", + "libraryPackage": "google.cloud.retail_v2beta", + "protoPackage": "google.cloud.retail.v2beta", + "schema": "1.0", + "services": { + "CatalogService": { + "clients": { + "grpc": { + "libraryClient": "CatalogServiceClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CatalogServiceAsyncClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + }, + "rest": { + "libraryClient": "CatalogServiceClient", + "rpcs": { + "AddCatalogAttribute": { + "methods": [ + "add_catalog_attribute" + ] + }, + "BatchRemoveCatalogAttributes": { + "methods": [ + "batch_remove_catalog_attributes" + ] + }, + "GetAttributesConfig": { + "methods": [ + "get_attributes_config" + ] + }, + "GetCompletionConfig": { + "methods": [ + "get_completion_config" + ] + }, + "GetDefaultBranch": { + "methods": [ + "get_default_branch" + ] + }, + "ListCatalogs": { + "methods": [ + "list_catalogs" + ] + }, + "RemoveCatalogAttribute": { + "methods": [ + "remove_catalog_attribute" + ] + }, + "ReplaceCatalogAttribute": { + "methods": [ + "replace_catalog_attribute" + ] + }, + "SetDefaultBranch": { + "methods": [ + "set_default_branch" + ] + }, + "UpdateAttributesConfig": { + "methods": [ + "update_attributes_config" + ] + }, + "UpdateCatalog": { + "methods": [ + "update_catalog" + ] + }, + "UpdateCompletionConfig": { + "methods": [ + "update_completion_config" + ] + } + } + } + } + }, + "CompletionService": { + "clients": { + "grpc": { + "libraryClient": "CompletionServiceClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + }, + "grpc-async": { + "libraryClient": "CompletionServiceAsyncClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + }, + "rest": { + "libraryClient": "CompletionServiceClient", + "rpcs": { + "CompleteQuery": { + "methods": [ + "complete_query" + ] + }, + "ImportCompletionData": { + "methods": [ + "import_completion_data" + ] + } + } + } + } + }, + "ControlService": { + "clients": { + "grpc": { + "libraryClient": "ControlServiceClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ControlServiceAsyncClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + }, + "rest": { + "libraryClient": "ControlServiceClient", + "rpcs": { + "CreateControl": { + "methods": [ + "create_control" + ] + }, + "DeleteControl": { + "methods": [ + "delete_control" + ] + }, + "GetControl": { + "methods": [ + "get_control" + ] + }, + "ListControls": { + "methods": [ + "list_controls" + ] + }, + "UpdateControl": { + "methods": [ + "update_control" + ] + } + } + } + } + }, + "ModelService": { + "clients": { + "grpc": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ModelServiceAsyncClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + }, + "rest": { + "libraryClient": "ModelServiceClient", + "rpcs": { + "CreateModel": { + "methods": [ + "create_model" + ] + }, + "DeleteModel": { + "methods": [ + "delete_model" + ] + }, + "GetModel": { + "methods": [ + "get_model" + ] + }, + "ListModels": { + "methods": [ + "list_models" + ] + }, + "PauseModel": { + "methods": [ + "pause_model" + ] + }, + "ResumeModel": { + "methods": [ + "resume_model" + ] + }, + "TuneModel": { + "methods": [ + "tune_model" + ] + }, + "UpdateModel": { + "methods": [ + "update_model" + ] + } + } + } + } + }, + "PredictionService": { + "clients": { + "grpc": { + "libraryClient": "PredictionServiceClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + }, + "grpc-async": { + "libraryClient": "PredictionServiceAsyncClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + }, + "rest": { + "libraryClient": "PredictionServiceClient", + "rpcs": { + "Predict": { + "methods": [ + "predict" + ] + } + } + } + } + }, + "ProductService": { + "clients": { + "grpc": { + "libraryClient": "ProductServiceClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ProductServiceAsyncClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + }, + "rest": { + "libraryClient": "ProductServiceClient", + "rpcs": { + "AddFulfillmentPlaces": { + "methods": [ + "add_fulfillment_places" + ] + }, + "AddLocalInventories": { + "methods": [ + "add_local_inventories" + ] + }, + "CreateProduct": { + "methods": [ + "create_product" + ] + }, + "DeleteProduct": { + "methods": [ + "delete_product" + ] + }, + "GetProduct": { + "methods": [ + "get_product" + ] + }, + "ImportProducts": { + "methods": [ + "import_products" + ] + }, + "ListProducts": { + "methods": [ + "list_products" + ] + }, + "RemoveFulfillmentPlaces": { + "methods": [ + "remove_fulfillment_places" + ] + }, + "RemoveLocalInventories": { + "methods": [ + "remove_local_inventories" + ] + }, + "SetInventory": { + "methods": [ + "set_inventory" + ] + }, + "UpdateProduct": { + "methods": [ + "update_product" + ] + } + } + } + } + }, + "SearchService": { + "clients": { + "grpc": { + "libraryClient": "SearchServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "grpc-async": { + "libraryClient": "SearchServiceAsyncClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + }, + "rest": { + "libraryClient": "SearchServiceClient", + "rpcs": { + "Search": { + "methods": [ + "search" + ] + } + } + } + } + }, + "ServingConfigService": { + "clients": { + "grpc": { + "libraryClient": "ServingConfigServiceClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + }, + "grpc-async": { + "libraryClient": "ServingConfigServiceAsyncClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + }, + "rest": { + "libraryClient": "ServingConfigServiceClient", + "rpcs": { + "AddControl": { + "methods": [ + "add_control" + ] + }, + "CreateServingConfig": { + "methods": [ + "create_serving_config" + ] + }, + "DeleteServingConfig": { + "methods": [ + "delete_serving_config" + ] + }, + "GetServingConfig": { + "methods": [ + "get_serving_config" + ] + }, + "ListServingConfigs": { + "methods": [ + "list_serving_configs" + ] + }, + "RemoveControl": { + "methods": [ + "remove_control" + ] + }, + "UpdateServingConfig": { + "methods": [ + "update_serving_config" + ] + } + } + } + } + }, + "UserEventService": { + "clients": { + "grpc": { + "libraryClient": "UserEventServiceClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + }, + "grpc-async": { + "libraryClient": "UserEventServiceAsyncClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + }, + "rest": { + "libraryClient": "UserEventServiceClient", + "rpcs": { + "CollectUserEvent": { + "methods": [ + "collect_user_event" + ] + }, + "ImportUserEvents": { + "methods": [ + "import_user_events" + ] + }, + "PurgeUserEvents": { + "methods": [ + "purge_user_events" + ] + }, + "RejoinUserEvents": { + "methods": [ + "rejoin_user_events" + ] + }, + "WriteUserEvent": { + "methods": [ + "write_user_event" + ] + } + } + } + } + } + } +} diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/gapic_version.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/gapic_version.py new file mode 100644 index 00000000..360a0d13 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/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/v2beta/google/cloud/retail_v2beta/py.typed b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/py.typed new file mode 100644 index 00000000..fda82836 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/py.typed @@ -0,0 +1,2 @@ +# Marker file for PEP 561. +# The google-cloud-retail package uses inline types. diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/__init__.py new file mode 100644 index 00000000..89a37dc9 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/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/v2beta/google/cloud/retail_v2beta/services/catalog_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/__init__.py new file mode 100644 index 00000000..339851f1 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/__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 CatalogServiceClient +from .async_client import CatalogServiceAsyncClient + +__all__ = ( + 'CatalogServiceClient', + 'CatalogServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/async_client.py new file mode 100644 index 00000000..a210a03e --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/async_client.py @@ -0,0 +1,1611 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.catalog_service import pagers +from google.cloud.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog as gcr_catalog +from google.cloud.retail_v2beta.types import catalog_service +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .client import CatalogServiceClient + + +class CatalogServiceAsyncClient: + """Service for managing catalog configuration.""" + + _client: CatalogServiceClient + + DEFAULT_ENDPOINT = CatalogServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CatalogServiceClient.DEFAULT_MTLS_ENDPOINT + + attributes_config_path = staticmethod(CatalogServiceClient.attributes_config_path) + parse_attributes_config_path = staticmethod(CatalogServiceClient.parse_attributes_config_path) + branch_path = staticmethod(CatalogServiceClient.branch_path) + parse_branch_path = staticmethod(CatalogServiceClient.parse_branch_path) + catalog_path = staticmethod(CatalogServiceClient.catalog_path) + parse_catalog_path = staticmethod(CatalogServiceClient.parse_catalog_path) + completion_config_path = staticmethod(CatalogServiceClient.completion_config_path) + parse_completion_config_path = staticmethod(CatalogServiceClient.parse_completion_config_path) + common_billing_account_path = staticmethod(CatalogServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CatalogServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CatalogServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CatalogServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CatalogServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CatalogServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CatalogServiceClient.common_project_path) + parse_common_project_path = staticmethod(CatalogServiceClient.parse_common_project_path) + common_location_path = staticmethod(CatalogServiceClient.common_location_path) + parse_common_location_path = staticmethod(CatalogServiceClient.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: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_info.__func__(CatalogServiceAsyncClient, 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: + CatalogServiceAsyncClient: The constructed client. + """ + return CatalogServiceClient.from_service_account_file.__func__(CatalogServiceAsyncClient, 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 CatalogServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CatalogServiceClient).get_transport_class, type(CatalogServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CatalogServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service 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, ~.CatalogServiceTransport]): 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 = CatalogServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def list_catalogs(self, + request: Optional[Union[catalog_service.ListCatalogsRequest, 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.ListCatalogsAsyncPager: + r"""Lists all the [Catalog][google.cloud.retail.v2beta.Catalog]s + associated with the project. + + .. 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 retail_v2beta + + async def sample_list_catalogs(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ListCatalogsRequest, dict]]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + method. + parent (:class:`str`): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2beta.Catalog]s under + this location, regardless of whether or not this + location exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2beta.services.catalog_service.pagers.ListCatalogsAsyncPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + 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 = catalog_service.ListCatalogsRequest(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_catalogs, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListCatalogsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_catalog(self, + request: Optional[Union[catalog_service.UpdateCatalogRequest, dict]] = None, + *, + catalog: Optional[gcr_catalog.Catalog] = 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]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2beta.Catalog]s. + + .. 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 retail_v2beta + + async def sample_update_catalog(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog = retail_v2beta.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2beta.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = await client.update_catalog(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.UpdateCatalogRequest, dict]]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2beta.CatalogService.UpdateCatalog] + method. + catalog (:class:`google.cloud.retail_v2beta.types.Catalog`): + Required. The + [Catalog][google.cloud.retail.v2beta.Catalog] to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2beta.Catalog], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Catalog][google.cloud.retail.v2beta.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2beta.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + 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.retail_v2beta.types.Catalog: + The catalog configuration. + """ + # 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([catalog, 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 = catalog_service.UpdateCatalogRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + 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_catalog, + 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(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def set_default_branch(self, + request: Optional[Union[catalog_service.SetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + .. 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 retail_v2beta + + async def sample_set_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.SetDefaultBranchRequest( + ) + + # Make the request + await client.set_default_branch(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.SetDefaultBranchRequest, dict]]): + The request object. Request message to set a specified branch as new + default_branch. + catalog (:class:`str`): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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([catalog]) + 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 = catalog_service.SetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.set_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def get_default_branch(self, + request: Optional[Union[catalog_service.GetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2beta.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + .. 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 retail_v2beta + + async def sample_get_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetDefaultBranchRequest( + ) + + # Make the request + response = await client.get_default_branch(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.GetDefaultBranchRequest, dict]]): + The request object. Request message to show which branch + is currently the default branch. + catalog (:class:`str`): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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.retail_v2beta.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2beta.CatalogService.GetDefaultBranch]. + + """ + # 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([catalog]) + 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 = catalog_service.GetDefaultBranchRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # 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_default_branch, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_completion_config(self, + request: Optional[Union[catalog_service.GetCompletionConfigRequest, 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]] = (), + ) -> catalog.CompletionConfig: + r"""Gets a + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]. + + .. 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 retail_v2beta + + async def sample_get_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.GetCompletionConfigRequest, dict]]): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2beta.CatalogService.GetCompletionConfig] + method. + name (:class:`str`): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + + 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.retail_v2beta.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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 = catalog_service.GetCompletionConfigRequest(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_completion_config, + 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(( + ("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_completion_config(self, + request: Optional[Union[catalog_service.UpdateCompletionConfigRequest, dict]] = None, + *, + completion_config: Optional[catalog.CompletionConfig] = 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]] = (), + ) -> catalog.CompletionConfig: + r"""Updates the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]s. + + .. 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 retail_v2beta + + async def sample_update_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + completion_config = retail_v2beta.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2beta.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = await client.update_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.UpdateCompletionConfigRequest, dict]]): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2beta.CatalogService.UpdateCompletionConfig] + method. + completion_config (:class:`google.cloud.retail_v2beta.types.CompletionConfig`): + Required. The + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``completion_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2beta.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2beta.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2beta.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2beta.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + + 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.retail_v2beta.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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([completion_config, 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 = catalog_service.UpdateCompletionConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if completion_config is not None: + request.completion_config = completion_config + 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_completion_config, + 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(( + ("completion_config.name", request.completion_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_attributes_config(self, + request: Optional[Union[catalog_service.GetAttributesConfigRequest, 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]] = (), + ) -> catalog.AttributesConfig: + r"""Gets an + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + .. 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 retail_v2beta + + async def sample_get_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.GetAttributesConfigRequest, dict]]): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2beta.CatalogService.GetAttributesConfig] + method. + name (:class:`str`): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + + 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.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # 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 = catalog_service.GetAttributesConfigRequest(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_attributes_config, + 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(( + ("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_attributes_config(self, + request: Optional[Union[catalog_service.UpdateAttributesConfigRequest, dict]] = None, + *, + attributes_config: Optional[catalog.AttributesConfig] = 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]] = (), + ) -> catalog.AttributesConfig: + r"""Updates the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + .. 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 retail_v2beta + + async def sample_update_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + attributes_config = retail_v2beta.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2beta.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = await client.update_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.UpdateAttributesConfigRequest, dict]]): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig] + method. + attributes_config (:class:`google.cloud.retail_v2beta.types.AttributesConfig`): + Required. The + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + to update. + + This corresponds to the ``attributes_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2beta.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + + 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.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # 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([attributes_config, 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 = catalog_service.UpdateAttributesConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if attributes_config is not None: + request.attributes_config = attributes_config + 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_attributes_config, + 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(( + ("attributes_config.name", request.attributes_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_catalog_attribute(self, + request: Optional[Union[catalog_service.AddCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Adds the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2beta + + async def sample_add_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.AddCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute] + 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: + google.cloud.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.AddCatalogAttributeRequest(request) + + # 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_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_catalog_attribute(self, + request: Optional[Union[catalog_service.RemoveCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Removes the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + async def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = await client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.RemoveCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2beta.CatalogService.RemoveCatalogAttribute] + 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: + google.cloud.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.RemoveCatalogAttributeRequest(request) + + # 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_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def batch_remove_catalog_attributes(self, + request: Optional[Union[catalog_service.BatchRemoveCatalogAttributesRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + .. 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 retail_v2beta + + async def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = await client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest, dict]]): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes] + 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: + google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]. + + """ + # Create or coerce a protobuf request object. + request = catalog_service.BatchRemoveCatalogAttributesRequest(request) + + # 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_remove_catalog_attributes, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def replace_catalog_attribute(self, + request: Optional[Union[catalog_service.ReplaceCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Replaces the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2beta.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + async def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ReplaceCatalogAttributeRequest, dict]]): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute] + 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: + google.cloud.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + request = catalog_service.ReplaceCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.replace_catalog_attribute, + 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(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CatalogServiceAsyncClient": + 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__ = ( + "CatalogServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/client.py new file mode 100644 index 00000000..0da1aca5 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/client.py @@ -0,0 +1,1849 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.catalog_service import pagers +from google.cloud.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog as gcr_catalog +from google.cloud.retail_v2beta.types import catalog_service +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CatalogServiceGrpcTransport +from .transports.grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .transports.rest import CatalogServiceRestTransport + + +class CatalogServiceClientMeta(type): + """Metaclass for the CatalogService 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[CatalogServiceTransport]] + _transport_registry["grpc"] = CatalogServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CatalogServiceGrpcAsyncIOTransport + _transport_registry["rest"] = CatalogServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[CatalogServiceTransport]: + """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 CatalogServiceClient(metaclass=CatalogServiceClientMeta): + """Service for managing catalog configuration.""" + + @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 = "retail.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: + CatalogServiceClient: 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: + CatalogServiceClient: 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) -> CatalogServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CatalogServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def attributes_config_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified attributes_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/attributesConfig".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_attributes_config_path(path: str) -> Dict[str,str]: + """Parses a attributes_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/attributesConfig$", path) + return m.groupdict() if m else {} + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def completion_config_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified completion_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/completionConfig".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_completion_config_path(path: str) -> Dict[str,str]: + """Parses a completion_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/completionConfig$", 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, CatalogServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the catalog service 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, CatalogServiceTransport]): 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, CatalogServiceTransport): + # transport is a CatalogServiceTransport 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 list_catalogs(self, + request: Optional[Union[catalog_service.ListCatalogsRequest, 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.ListCatalogsPager: + r"""Lists all the [Catalog][google.cloud.retail.v2beta.Catalog]s + associated with the project. + + .. 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 retail_v2beta + + def sample_list_catalogs(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ListCatalogsRequest, dict]): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + method. + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2beta.Catalog]s under + this location, regardless of whether or not this + location exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2beta.services.catalog_service.pagers.ListCatalogsPager: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + 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 catalog_service.ListCatalogsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.ListCatalogsRequest): + request = catalog_service.ListCatalogsRequest(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_catalogs] + + # 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.ListCatalogsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_catalog(self, + request: Optional[Union[catalog_service.UpdateCatalogRequest, dict]] = None, + *, + catalog: Optional[gcr_catalog.Catalog] = 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]] = (), + ) -> gcr_catalog.Catalog: + r"""Updates the [Catalog][google.cloud.retail.v2beta.Catalog]s. + + .. 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 retail_v2beta + + def sample_update_catalog(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + catalog = retail_v2beta.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2beta.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = client.update_catalog(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateCatalogRequest, dict]): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2beta.CatalogService.UpdateCatalog] + method. + catalog (google.cloud.retail_v2beta.types.Catalog): + Required. The + [Catalog][google.cloud.retail.v2beta.Catalog] to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2beta.Catalog], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Catalog][google.cloud.retail.v2beta.Catalog] to + update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``catalog`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2beta.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + 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.retail_v2beta.types.Catalog: + The catalog configuration. + """ + # 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([catalog, 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 catalog_service.UpdateCatalogRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateCatalogRequest): + request = catalog_service.UpdateCatalogRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + 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_catalog] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog.name", request.catalog.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def set_default_branch(self, + request: Optional[Union[catalog_service.SetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> None: + r"""Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + .. 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 retail_v2beta + + def sample_set_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.SetDefaultBranchRequest( + ) + + # Make the request + client.set_default_branch(request=request) + + Args: + request (Union[google.cloud.retail_v2beta.types.SetDefaultBranchRequest, dict]): + The request object. Request message to set a specified branch as new + default_branch. + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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([catalog]) + 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 catalog_service.SetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.SetDefaultBranchRequest): + request = catalog_service.SetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + def get_default_branch(self, + request: Optional[Union[catalog_service.GetDefaultBranchRequest, dict]] = None, + *, + catalog: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2beta.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + .. 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 retail_v2beta + + def sample_get_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetDefaultBranchRequest( + ) + + # Make the request + response = client.get_default_branch(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetDefaultBranchRequest, dict]): + The request object. Request message to show which branch + is currently the default branch. + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + + This corresponds to the ``catalog`` 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.retail_v2beta.types.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2beta.CatalogService.GetDefaultBranch]. + + """ + # 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([catalog]) + 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 catalog_service.GetDefaultBranchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetDefaultBranchRequest): + request = catalog_service.GetDefaultBranchRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if catalog is not None: + request.catalog = catalog + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.get_default_branch] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_completion_config(self, + request: Optional[Union[catalog_service.GetCompletionConfigRequest, 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]] = (), + ) -> catalog.CompletionConfig: + r"""Gets a + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]. + + .. 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 retail_v2beta + + def sample_get_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetCompletionConfigRequest, dict]): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2beta.CatalogService.GetCompletionConfig] + method. + name (str): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + + 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.retail_v2beta.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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 catalog_service.GetCompletionConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetCompletionConfigRequest): + request = catalog_service.GetCompletionConfigRequest(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_completion_config] + + # 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_completion_config(self, + request: Optional[Union[catalog_service.UpdateCompletionConfigRequest, dict]] = None, + *, + completion_config: Optional[catalog.CompletionConfig] = 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]] = (), + ) -> catalog.CompletionConfig: + r"""Updates the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]s. + + .. 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 retail_v2beta + + def sample_update_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + completion_config = retail_v2beta.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2beta.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = client.update_completion_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateCompletionConfigRequest, dict]): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2beta.CatalogService.UpdateCompletionConfig] + method. + completion_config (google.cloud.retail_v2beta.types.CompletionConfig): + Required. The + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + + This corresponds to the ``completion_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2beta.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2beta.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2beta.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2beta.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + + 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.retail_v2beta.types.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + # 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([completion_config, 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 catalog_service.UpdateCompletionConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateCompletionConfigRequest): + request = catalog_service.UpdateCompletionConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if completion_config is not None: + request.completion_config = completion_config + 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_completion_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("completion_config.name", request.completion_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_attributes_config(self, + request: Optional[Union[catalog_service.GetAttributesConfigRequest, 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]] = (), + ) -> catalog.AttributesConfig: + r"""Gets an + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + .. 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 retail_v2beta + + def sample_get_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetAttributesConfigRequest, dict]): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2beta.CatalogService.GetAttributesConfig] + method. + name (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + + 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.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # 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 catalog_service.GetAttributesConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.GetAttributesConfigRequest): + request = catalog_service.GetAttributesConfigRequest(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_attributes_config] + + # 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_attributes_config(self, + request: Optional[Union[catalog_service.UpdateAttributesConfigRequest, dict]] = None, + *, + attributes_config: Optional[catalog.AttributesConfig] = 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]] = (), + ) -> catalog.AttributesConfig: + r"""Updates the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + .. 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 retail_v2beta + + def sample_update_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + attributes_config = retail_v2beta.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2beta.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = client.update_attributes_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateAttributesConfigRequest, dict]): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig] + method. + attributes_config (google.cloud.retail_v2beta.types.AttributesConfig): + Required. The + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + to update. + + This corresponds to the ``attributes_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2beta.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + + 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.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # 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([attributes_config, 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 catalog_service.UpdateAttributesConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.UpdateAttributesConfigRequest): + request = catalog_service.UpdateAttributesConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if attributes_config is not None: + request.attributes_config = attributes_config + 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_attributes_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config.name", request.attributes_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_catalog_attribute(self, + request: Optional[Union[catalog_service.AddCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Adds the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2beta + + def sample_add_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.AddCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute] + 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: + google.cloud.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.AddCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.AddCatalogAttributeRequest): + request = catalog_service.AddCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_catalog_attribute(self, + request: Optional[Union[catalog_service.RemoveCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Removes the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.RemoveCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2beta.CatalogService.RemoveCatalogAttribute] + 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: + google.cloud.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.RemoveCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.RemoveCatalogAttributeRequest): + request = catalog_service.RemoveCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def batch_remove_catalog_attributes(self, + request: Optional[Union[catalog_service.BatchRemoveCatalogAttributesRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + .. 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 retail_v2beta + + def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest, dict]): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes] + 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: + google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.BatchRemoveCatalogAttributesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.BatchRemoveCatalogAttributesRequest): + request = catalog_service.BatchRemoveCatalogAttributesRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.batch_remove_catalog_attributes] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def replace_catalog_attribute(self, + request: Optional[Union[catalog_service.ReplaceCatalogAttributeRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> catalog.AttributesConfig: + r"""Replaces the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2beta.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ReplaceCatalogAttributeRequest, dict]): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute] + 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: + google.cloud.retail_v2beta.types.AttributesConfig: + Catalog level attribute config. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a catalog_service.ReplaceCatalogAttributeRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, catalog_service.ReplaceCatalogAttributeRequest): + request = catalog_service.ReplaceCatalogAttributeRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.replace_catalog_attribute] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("attributes_config", request.attributes_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CatalogServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "CatalogServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/pagers.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/pagers.py new file mode 100644 index 00000000..54c8e2b2 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog_service + + +class ListCatalogsPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListCatalogsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListCatalogsResponse` + 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[..., catalog_service.ListCatalogsResponse], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + 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.retail_v2beta.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListCatalogsResponse): + 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 = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[catalog_service.ListCatalogsResponse]: + 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[catalog.Catalog]: + for page in self.pages: + yield from page.catalogs + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListCatalogsAsyncPager: + """A pager for iterating through ``list_catalogs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListCatalogsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``catalogs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListCatalogs`` requests and continue to iterate + through the ``catalogs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListCatalogsResponse` + 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[catalog_service.ListCatalogsResponse]], + request: catalog_service.ListCatalogsRequest, + response: catalog_service.ListCatalogsResponse, + *, + 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.retail_v2beta.types.ListCatalogsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListCatalogsResponse): + 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 = catalog_service.ListCatalogsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[catalog_service.ListCatalogsResponse]: + 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[catalog.Catalog]: + async def async_generator(): + async for page in self.pages: + for response in page.catalogs: + 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/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/__init__.py new file mode 100644 index 00000000..12110418 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/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 CatalogServiceTransport +from .grpc import CatalogServiceGrpcTransport +from .grpc_asyncio import CatalogServiceGrpcAsyncIOTransport +from .rest import CatalogServiceRestTransport +from .rest import CatalogServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CatalogServiceTransport]] +_transport_registry['grpc'] = CatalogServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CatalogServiceGrpcAsyncIOTransport +_transport_registry['rest'] = CatalogServiceRestTransport + +__all__ = ( + 'CatalogServiceTransport', + 'CatalogServiceGrpcTransport', + 'CatalogServiceGrpcAsyncIOTransport', + 'CatalogServiceRestTransport', + 'CatalogServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/base.py new file mode 100644 index 00000000..a25628d6 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/base.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog as gcr_catalog +from google.cloud.retail_v2beta.types import catalog_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 CatalogServiceTransport(abc.ABC): + """Abstract transport class for CatalogService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.list_catalogs: gapic_v1.method.wrap_method( + self.list_catalogs, + default_timeout=None, + client_info=client_info, + ), + self.update_catalog: gapic_v1.method.wrap_method( + self.update_catalog, + default_timeout=None, + client_info=client_info, + ), + self.set_default_branch: gapic_v1.method.wrap_method( + self.set_default_branch, + default_timeout=None, + client_info=client_info, + ), + self.get_default_branch: gapic_v1.method.wrap_method( + self.get_default_branch, + default_timeout=None, + client_info=client_info, + ), + self.get_completion_config: gapic_v1.method.wrap_method( + self.get_completion_config, + default_timeout=None, + client_info=client_info, + ), + self.update_completion_config: gapic_v1.method.wrap_method( + self.update_completion_config, + default_timeout=None, + client_info=client_info, + ), + self.get_attributes_config: gapic_v1.method.wrap_method( + self.get_attributes_config, + default_timeout=None, + client_info=client_info, + ), + self.update_attributes_config: gapic_v1.method.wrap_method( + self.update_attributes_config, + default_timeout=None, + client_info=client_info, + ), + self.add_catalog_attribute: gapic_v1.method.wrap_method( + self.add_catalog_attribute, + default_timeout=None, + client_info=client_info, + ), + self.remove_catalog_attribute: gapic_v1.method.wrap_method( + self.remove_catalog_attribute, + default_timeout=None, + client_info=client_info, + ), + self.batch_remove_catalog_attributes: gapic_v1.method.wrap_method( + self.batch_remove_catalog_attributes, + default_timeout=None, + client_info=client_info, + ), + self.replace_catalog_attribute: gapic_v1.method.wrap_method( + self.replace_catalog_attribute, + 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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Union[ + catalog_service.ListCatalogsResponse, + Awaitable[catalog_service.ListCatalogsResponse] + ]]: + raise NotImplementedError() + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Union[ + gcr_catalog.Catalog, + Awaitable[gcr_catalog.Catalog] + ]]: + raise NotImplementedError() + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Union[ + catalog_service.GetDefaultBranchResponse, + Awaitable[catalog_service.GetDefaultBranchResponse] + ]]: + raise NotImplementedError() + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + Union[ + catalog.CompletionConfig, + Awaitable[catalog.CompletionConfig] + ]]: + raise NotImplementedError() + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + Union[ + catalog.CompletionConfig, + Awaitable[catalog.CompletionConfig] + ]]: + raise NotImplementedError() + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + Union[ + catalog_service.BatchRemoveCatalogAttributesResponse, + Awaitable[catalog_service.BatchRemoveCatalogAttributesResponse] + ]]: + raise NotImplementedError() + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + Union[ + catalog.AttributesConfig, + Awaitable[catalog.AttributesConfig] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'CatalogServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.py new file mode 100644 index 00000000..117e2407 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc.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. +# +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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog as gcr_catalog +from google.cloud.retail_v2beta.types import catalog_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO + + +class CatalogServiceGrpcTransport(CatalogServiceTransport): + """gRPC backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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 = 'retail.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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + catalog_service.ListCatalogsResponse]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2beta.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + ~.ListCatalogsResponse]: + 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_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + gcr_catalog.Catalog]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2beta.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + ~.Catalog]: + 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_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + empty_pb2.Empty]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + Returns: + Callable[[~.SetDefaultBranchRequest], + ~.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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + catalog_service.GetDefaultBranchResponse]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2beta.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + Returns: + Callable[[~.GetDefaultBranchRequest], + ~.GetDefaultBranchResponse]: + 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_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + catalog.CompletionConfig]: + r"""Return a callable for the get completion config method over gRPC. + + Gets a + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]. + + Returns: + Callable[[~.GetCompletionConfigRequest], + ~.CompletionConfig]: + 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_completion_config' not in self._stubs: + self._stubs['get_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/GetCompletionConfig', + request_serializer=catalog_service.GetCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['get_completion_config'] + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + catalog.CompletionConfig]: + r"""Return a callable for the update completion config method over gRPC. + + Updates the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]s. + + Returns: + Callable[[~.UpdateCompletionConfigRequest], + ~.CompletionConfig]: + 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_completion_config' not in self._stubs: + self._stubs['update_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/UpdateCompletionConfig', + request_serializer=catalog_service.UpdateCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['update_completion_config'] + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + catalog.AttributesConfig]: + r"""Return a callable for the get attributes config method over gRPC. + + Gets an + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + Returns: + Callable[[~.GetAttributesConfigRequest], + ~.AttributesConfig]: + 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_attributes_config' not in self._stubs: + self._stubs['get_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/GetAttributesConfig', + request_serializer=catalog_service.GetAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['get_attributes_config'] + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + catalog.AttributesConfig]: + r"""Return a callable for the update attributes config method over gRPC. + + Updates the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + Returns: + Callable[[~.UpdateAttributesConfigRequest], + ~.AttributesConfig]: + 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_attributes_config' not in self._stubs: + self._stubs['update_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/UpdateAttributesConfig', + request_serializer=catalog_service.UpdateAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['update_attributes_config'] + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the add catalog attribute method over gRPC. + + Adds the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.AddCatalogAttributeRequest], + ~.AttributesConfig]: + 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_catalog_attribute' not in self._stubs: + self._stubs['add_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/AddCatalogAttribute', + request_serializer=catalog_service.AddCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['add_catalog_attribute'] + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the remove catalog attribute method over gRPC. + + Removes the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.RemoveCatalogAttributeRequest], + ~.AttributesConfig]: + 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_catalog_attribute' not in self._stubs: + self._stubs['remove_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/RemoveCatalogAttribute', + request_serializer=catalog_service.RemoveCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['remove_catalog_attribute'] + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + catalog_service.BatchRemoveCatalogAttributesResponse]: + r"""Return a callable for the batch remove catalog + attributes method over gRPC. + + Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + Returns: + Callable[[~.BatchRemoveCatalogAttributesRequest], + ~.BatchRemoveCatalogAttributesResponse]: + 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_remove_catalog_attributes' not in self._stubs: + self._stubs['batch_remove_catalog_attributes'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/BatchRemoveCatalogAttributes', + request_serializer=catalog_service.BatchRemoveCatalogAttributesRequest.serialize, + response_deserializer=catalog_service.BatchRemoveCatalogAttributesResponse.deserialize, + ) + return self._stubs['batch_remove_catalog_attributes'] + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + catalog.AttributesConfig]: + r"""Return a callable for the replace catalog attribute method over gRPC. + + Replaces the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2beta.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.ReplaceCatalogAttributeRequest], + ~.AttributesConfig]: + 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 'replace_catalog_attribute' not in self._stubs: + self._stubs['replace_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/ReplaceCatalogAttribute', + request_serializer=catalog_service.ReplaceCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['replace_catalog_attribute'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'CatalogServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..1f9f2313 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/grpc_asyncio.py @@ -0,0 +1,667 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog as gcr_catalog +from google.cloud.retail_v2beta.types import catalog_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import CatalogServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CatalogServiceGrpcTransport + + +class CatalogServiceGrpcAsyncIOTransport(CatalogServiceTransport): + """gRPC AsyncIO backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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 = 'retail.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 list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + Awaitable[catalog_service.ListCatalogsResponse]]: + r"""Return a callable for the list catalogs method over gRPC. + + Lists all the [Catalog][google.cloud.retail.v2beta.Catalog]s + associated with the project. + + Returns: + Callable[[~.ListCatalogsRequest], + Awaitable[~.ListCatalogsResponse]]: + 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_catalogs' not in self._stubs: + self._stubs['list_catalogs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/ListCatalogs', + request_serializer=catalog_service.ListCatalogsRequest.serialize, + response_deserializer=catalog_service.ListCatalogsResponse.deserialize, + ) + return self._stubs['list_catalogs'] + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + Awaitable[gcr_catalog.Catalog]]: + r"""Return a callable for the update catalog method over gRPC. + + Updates the [Catalog][google.cloud.retail.v2beta.Catalog]s. + + Returns: + Callable[[~.UpdateCatalogRequest], + Awaitable[~.Catalog]]: + 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_catalog' not in self._stubs: + self._stubs['update_catalog'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/UpdateCatalog', + request_serializer=catalog_service.UpdateCatalogRequest.serialize, + response_deserializer=gcr_catalog.Catalog.deserialize, + ) + return self._stubs['update_catalog'] + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the set default branch method over gRPC. + + Set a specified branch id as default branch. API methods such as + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search], + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct], + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + will treat requests using "default_branch" to the actual branch + id set as default. + + For example, if ``projects/*/locations/*/catalogs/*/branches/1`` + is set as default, setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/default_branch`` + is equivalent to setting + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to ``projects/*/locations/*/catalogs/*/branches/1``. + + Using multiple branches can be useful when developers would like + to have a staging branch to test and verify for future usage. + When it becomes ready, developers switch on the staging branch + using this API while keeping using + ``projects/*/locations/*/catalogs/*/branches/default_branch`` as + [SearchRequest.branch][google.cloud.retail.v2beta.SearchRequest.branch] + to route the traffic to this staging branch. + + CAUTION: If you have live predict/search traffic, switching the + default branch could potentially cause outages if the ID space + of the new branch is very different from the old one. + + More specifically: + + - PredictionService will only return product IDs from branch + {newBranch}. + - SearchService will only return product IDs from branch + {newBranch} (if branch is not explicitly set). + - UserEventService will only join events with products from + branch {newBranch}. + + Returns: + Callable[[~.SetDefaultBranchRequest], + 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 'set_default_branch' not in self._stubs: + self._stubs['set_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/SetDefaultBranch', + request_serializer=catalog_service.SetDefaultBranchRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['set_default_branch'] + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + Awaitable[catalog_service.GetDefaultBranchResponse]]: + r"""Return a callable for the get default branch method over gRPC. + + Get which branch is currently default branch set by + [CatalogService.SetDefaultBranch][google.cloud.retail.v2beta.CatalogService.SetDefaultBranch] + method under a specified parent catalog. + + Returns: + Callable[[~.GetDefaultBranchRequest], + Awaitable[~.GetDefaultBranchResponse]]: + 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_default_branch' not in self._stubs: + self._stubs['get_default_branch'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/GetDefaultBranch', + request_serializer=catalog_service.GetDefaultBranchRequest.serialize, + response_deserializer=catalog_service.GetDefaultBranchResponse.deserialize, + ) + return self._stubs['get_default_branch'] + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + Awaitable[catalog.CompletionConfig]]: + r"""Return a callable for the get completion config method over gRPC. + + Gets a + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]. + + Returns: + Callable[[~.GetCompletionConfigRequest], + Awaitable[~.CompletionConfig]]: + 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_completion_config' not in self._stubs: + self._stubs['get_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/GetCompletionConfig', + request_serializer=catalog_service.GetCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['get_completion_config'] + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + Awaitable[catalog.CompletionConfig]]: + r"""Return a callable for the update completion config method over gRPC. + + Updates the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig]s. + + Returns: + Callable[[~.UpdateCompletionConfigRequest], + Awaitable[~.CompletionConfig]]: + 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_completion_config' not in self._stubs: + self._stubs['update_completion_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/UpdateCompletionConfig', + request_serializer=catalog_service.UpdateCompletionConfigRequest.serialize, + response_deserializer=catalog.CompletionConfig.deserialize, + ) + return self._stubs['update_completion_config'] + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the get attributes config method over gRPC. + + Gets an + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + Returns: + Callable[[~.GetAttributesConfigRequest], + Awaitable[~.AttributesConfig]]: + 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_attributes_config' not in self._stubs: + self._stubs['get_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/GetAttributesConfig', + request_serializer=catalog_service.GetAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['get_attributes_config'] + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the update attributes config method over gRPC. + + Updates the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + The catalog attributes in the request will be updated in the + catalog, or inserted if they do not exist. Existing catalog + attributes not included in the request will remain unchanged. + Attributes that are assigned to products, but do not exist at + the catalog level, are always included in the response. The + product attribute is assigned default values for missing catalog + attribute fields, e.g., searchable and dynamic facetable + options. + + Returns: + Callable[[~.UpdateAttributesConfigRequest], + Awaitable[~.AttributesConfig]]: + 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_attributes_config' not in self._stubs: + self._stubs['update_attributes_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/UpdateAttributesConfig', + request_serializer=catalog_service.UpdateAttributesConfigRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['update_attributes_config'] + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the add catalog attribute method over gRPC. + + Adds the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to add already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.AddCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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_catalog_attribute' not in self._stubs: + self._stubs['add_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/AddCatalogAttribute', + request_serializer=catalog_service.AddCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['add_catalog_attribute'] + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the remove catalog attribute method over gRPC. + + Removes the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to remove does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.RemoveCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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_catalog_attribute' not in self._stubs: + self._stubs['remove_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/RemoveCatalogAttribute', + request_serializer=catalog_service.RemoveCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['remove_catalog_attribute'] + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + Awaitable[catalog_service.BatchRemoveCatalogAttributesResponse]]: + r"""Return a callable for the batch remove catalog + attributes method over gRPC. + + Removes all specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + from the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig]. + + Returns: + Callable[[~.BatchRemoveCatalogAttributesRequest], + Awaitable[~.BatchRemoveCatalogAttributesResponse]]: + 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_remove_catalog_attributes' not in self._stubs: + self._stubs['batch_remove_catalog_attributes'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/BatchRemoveCatalogAttributes', + request_serializer=catalog_service.BatchRemoveCatalogAttributesRequest.serialize, + response_deserializer=catalog_service.BatchRemoveCatalogAttributesResponse.deserialize, + ) + return self._stubs['batch_remove_catalog_attributes'] + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + Awaitable[catalog.AttributesConfig]]: + r"""Return a callable for the replace catalog attribute method over gRPC. + + Replaces the specified + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + in the + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + by updating the catalog attribute with the same + [CatalogAttribute.key][google.cloud.retail.v2beta.CatalogAttribute.key]. + + If the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to replace does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.ReplaceCatalogAttributeRequest], + Awaitable[~.AttributesConfig]]: + 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 'replace_catalog_attribute' not in self._stubs: + self._stubs['replace_catalog_attribute'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CatalogService/ReplaceCatalogAttribute', + request_serializer=catalog_service.ReplaceCatalogAttributeRequest.serialize, + response_deserializer=catalog.AttributesConfig.deserialize, + ) + return self._stubs['replace_catalog_attribute'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'CatalogServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/rest.py new file mode 100644 index 00000000..61248f97 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/catalog_service/transports/rest.py @@ -0,0 +1,1762 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog as gcr_catalog +from google.cloud.retail_v2beta.types import catalog_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import CatalogServiceTransport, 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 CatalogServiceRestInterceptor: + """Interceptor for CatalogService. + + 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 CatalogServiceRestTransport. + + .. code-block:: python + class MyCustomCatalogServiceInterceptor(CatalogServiceRestInterceptor): + def pre_add_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_batch_remove_catalog_attributes(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_batch_remove_catalog_attributes(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_attributes_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_attributes_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_completion_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_completion_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_get_default_branch(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_default_branch(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_catalogs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_catalogs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_replace_catalog_attribute(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_replace_catalog_attribute(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_default_branch(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_update_attributes_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_attributes_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_catalog(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_catalog(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_completion_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_completion_config(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CatalogServiceRestTransport(interceptor=MyCustomCatalogServiceInterceptor()) + client = CatalogServiceClient(transport=transport) + + + """ + def pre_add_catalog_attribute(self, request: catalog_service.AddCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.AddCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_add_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for add_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_batch_remove_catalog_attributes(self, request: catalog_service.BatchRemoveCatalogAttributesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.BatchRemoveCatalogAttributesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for batch_remove_catalog_attributes + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_batch_remove_catalog_attributes(self, response: catalog_service.BatchRemoveCatalogAttributesResponse) -> catalog_service.BatchRemoveCatalogAttributesResponse: + """Post-rpc interceptor for batch_remove_catalog_attributes + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_attributes_config(self, request: catalog_service.GetAttributesConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetAttributesConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_attributes_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_attributes_config(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for get_attributes_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_completion_config(self, request: catalog_service.GetCompletionConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetCompletionConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_completion_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_completion_config(self, response: catalog.CompletionConfig) -> catalog.CompletionConfig: + """Post-rpc interceptor for get_completion_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_get_default_branch(self, request: catalog_service.GetDefaultBranchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.GetDefaultBranchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_default_branch + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_default_branch(self, response: catalog_service.GetDefaultBranchResponse) -> catalog_service.GetDefaultBranchResponse: + """Post-rpc interceptor for get_default_branch + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_list_catalogs(self, request: catalog_service.ListCatalogsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.ListCatalogsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_catalogs + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_list_catalogs(self, response: catalog_service.ListCatalogsResponse) -> catalog_service.ListCatalogsResponse: + """Post-rpc interceptor for list_catalogs + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_remove_catalog_attribute(self, request: catalog_service.RemoveCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.RemoveCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_remove_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for remove_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_replace_catalog_attribute(self, request: catalog_service.ReplaceCatalogAttributeRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.ReplaceCatalogAttributeRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for replace_catalog_attribute + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_replace_catalog_attribute(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for replace_catalog_attribute + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_set_default_branch(self, request: catalog_service.SetDefaultBranchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.SetDefaultBranchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_default_branch + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def pre_update_attributes_config(self, request: catalog_service.UpdateAttributesConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateAttributesConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_attributes_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_attributes_config(self, response: catalog.AttributesConfig) -> catalog.AttributesConfig: + """Post-rpc interceptor for update_attributes_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_update_catalog(self, request: catalog_service.UpdateCatalogRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateCatalogRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_catalog + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_catalog(self, response: gcr_catalog.Catalog) -> gcr_catalog.Catalog: + """Post-rpc interceptor for update_catalog + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_update_completion_config(self, request: catalog_service.UpdateCompletionConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[catalog_service.UpdateCompletionConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_completion_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_update_completion_config(self, response: catalog.CompletionConfig) -> catalog.CompletionConfig: + """Post-rpc interceptor for update_completion_config + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CatalogService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the CatalogService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CatalogServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CatalogServiceRestInterceptor + + +class CatalogServiceRestTransport(CatalogServiceTransport): + """REST backend transport for CatalogService. + + Service for managing catalog configuration. + + 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 = 'retail.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[CatalogServiceRestInterceptor] = 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 CatalogServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _AddCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("AddCatalogAttribute") + + __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: catalog_service.AddCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the add catalog attribute method over HTTP. + + Args: + request (~.catalog_service.AddCatalogAttributeRequest): + The request object. Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:addCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_catalog_attribute(request, metadata) + pb_request = catalog_service.AddCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_add_catalog_attribute(resp) + return resp + + class _BatchRemoveCatalogAttributes(CatalogServiceRestStub): + def __hash__(self): + return hash("BatchRemoveCatalogAttributes") + + __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: catalog_service.BatchRemoveCatalogAttributesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.BatchRemoveCatalogAttributesResponse: + r"""Call the batch remove catalog + attributes method over HTTP. + + Args: + request (~.catalog_service.BatchRemoveCatalogAttributesRequest): + The request object. Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes] + 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: + ~.catalog_service.BatchRemoveCatalogAttributesResponse: + Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:batchRemoveCatalogAttributes', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_batch_remove_catalog_attributes(request, metadata) + pb_request = catalog_service.BatchRemoveCatalogAttributesRequest.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 = catalog_service.BatchRemoveCatalogAttributesResponse() + pb_resp = catalog_service.BatchRemoveCatalogAttributesResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_batch_remove_catalog_attributes(resp) + return resp + + class _GetAttributesConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("GetAttributesConfig") + + __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: catalog_service.GetAttributesConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the get attributes config method over HTTP. + + Args: + request (~.catalog_service.GetAttributesConfigRequest): + The request object. Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2beta.CatalogService.GetAttributesConfig] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/attributesConfig}', + }, + ] + request, metadata = self._interceptor.pre_get_attributes_config(request, metadata) + pb_request = catalog_service.GetAttributesConfigRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_attributes_config(resp) + return resp + + class _GetCompletionConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("GetCompletionConfig") + + __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: catalog_service.GetCompletionConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.CompletionConfig: + r"""Call the get completion config method over HTTP. + + Args: + request (~.catalog_service.GetCompletionConfigRequest): + The request object. Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2beta.CatalogService.GetCompletionConfig] + 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: + ~.catalog.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/completionConfig}', + }, + ] + request, metadata = self._interceptor.pre_get_completion_config(request, metadata) + pb_request = catalog_service.GetCompletionConfigRequest.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 = catalog.CompletionConfig() + pb_resp = catalog.CompletionConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_completion_config(resp) + return resp + + class _GetDefaultBranch(CatalogServiceRestStub): + def __hash__(self): + return hash("GetDefaultBranch") + + def __call__(self, + request: catalog_service.GetDefaultBranchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.GetDefaultBranchResponse: + r"""Call the get default branch method over HTTP. + + Args: + request (~.catalog_service.GetDefaultBranchRequest): + The request object. Request message to show which branch + is currently the default branch. + 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: + ~.catalog_service.GetDefaultBranchResponse: + Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2beta.CatalogService.GetDefaultBranch]. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{catalog=projects/*/locations/*/catalogs/*}:getDefaultBranch', + }, + ] + request, metadata = self._interceptor.pre_get_default_branch(request, metadata) + pb_request = catalog_service.GetDefaultBranchRequest.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["$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 = catalog_service.GetDefaultBranchResponse() + pb_resp = catalog_service.GetDefaultBranchResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_default_branch(resp) + return resp + + class _ListCatalogs(CatalogServiceRestStub): + def __hash__(self): + return hash("ListCatalogs") + + __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: catalog_service.ListCatalogsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog_service.ListCatalogsResponse: + r"""Call the list catalogs method over HTTP. + + Args: + request (~.catalog_service.ListCatalogsRequest): + The request object. Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + 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: + ~.catalog_service.ListCatalogsResponse: + Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{parent=projects/*/locations/*}/catalogs', + }, + ] + request, metadata = self._interceptor.pre_list_catalogs(request, metadata) + pb_request = catalog_service.ListCatalogsRequest.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 = catalog_service.ListCatalogsResponse() + pb_resp = catalog_service.ListCatalogsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_catalogs(resp) + return resp + + class _RemoveCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("RemoveCatalogAttribute") + + __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: catalog_service.RemoveCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the remove catalog attribute method over HTTP. + + Args: + request (~.catalog_service.RemoveCatalogAttributeRequest): + The request object. Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2beta.CatalogService.RemoveCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:removeCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_catalog_attribute(request, metadata) + pb_request = catalog_service.RemoveCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_remove_catalog_attribute(resp) + return resp + + class _ReplaceCatalogAttribute(CatalogServiceRestStub): + def __hash__(self): + return hash("ReplaceCatalogAttribute") + + __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: catalog_service.ReplaceCatalogAttributeRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the replace catalog attribute method over HTTP. + + Args: + request (~.catalog_service.ReplaceCatalogAttributeRequest): + The request object. Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{attributes_config=projects/*/locations/*/catalogs/*/attributesConfig}:replaceCatalogAttribute', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_replace_catalog_attribute(request, metadata) + pb_request = catalog_service.ReplaceCatalogAttributeRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_replace_catalog_attribute(resp) + return resp + + class _SetDefaultBranch(CatalogServiceRestStub): + def __hash__(self): + return hash("SetDefaultBranch") + + def __call__(self, + request: catalog_service.SetDefaultBranchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the set default branch method over HTTP. + + Args: + request (~.catalog_service.SetDefaultBranchRequest): + The request object. Request message to set a specified branch as new + default_branch. + 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': '/v2beta/{catalog=projects/*/locations/*/catalogs/*}:setDefaultBranch', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_set_default_branch(request, metadata) + pb_request = catalog_service.SetDefaultBranchRequest.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["$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 _UpdateAttributesConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateAttributesConfig") + + __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: catalog_service.UpdateAttributesConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.AttributesConfig: + r"""Call the update attributes config method over HTTP. + + Args: + request (~.catalog_service.UpdateAttributesConfigRequest): + The request object. Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig] + 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: + ~.catalog.AttributesConfig: + Catalog level attribute config. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2beta/{attributes_config.name=projects/*/locations/*/catalogs/*/attributesConfig}', + 'body': 'attributes_config', + }, + ] + request, metadata = self._interceptor.pre_update_attributes_config(request, metadata) + pb_request = catalog_service.UpdateAttributesConfigRequest.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 = catalog.AttributesConfig() + pb_resp = catalog.AttributesConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_attributes_config(resp) + return resp + + class _UpdateCatalog(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateCatalog") + + __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: catalog_service.UpdateCatalogRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_catalog.Catalog: + r"""Call the update catalog method over HTTP. + + Args: + request (~.catalog_service.UpdateCatalogRequest): + The request object. Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2beta.CatalogService.UpdateCatalog] + 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: + ~.gcr_catalog.Catalog: + The catalog configuration. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2beta/{catalog.name=projects/*/locations/*/catalogs/*}', + 'body': 'catalog', + }, + ] + request, metadata = self._interceptor.pre_update_catalog(request, metadata) + pb_request = catalog_service.UpdateCatalogRequest.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 = gcr_catalog.Catalog() + pb_resp = gcr_catalog.Catalog.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_catalog(resp) + return resp + + class _UpdateCompletionConfig(CatalogServiceRestStub): + def __hash__(self): + return hash("UpdateCompletionConfig") + + __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: catalog_service.UpdateCompletionConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> catalog.CompletionConfig: + r"""Call the update completion config method over HTTP. + + Args: + request (~.catalog_service.UpdateCompletionConfigRequest): + The request object. Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2beta.CatalogService.UpdateCompletionConfig] + 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: + ~.catalog.CompletionConfig: + Catalog level autocomplete config for + customers to customize autocomplete + feature's settings. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2beta/{completion_config.name=projects/*/locations/*/catalogs/*/completionConfig}', + 'body': 'completion_config', + }, + ] + request, metadata = self._interceptor.pre_update_completion_config(request, metadata) + pb_request = catalog_service.UpdateCompletionConfigRequest.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 = catalog.CompletionConfig() + pb_resp = catalog.CompletionConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_completion_config(resp) + return resp + + @property + def add_catalog_attribute(self) -> Callable[ + [catalog_service.AddCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._AddCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def batch_remove_catalog_attributes(self) -> Callable[ + [catalog_service.BatchRemoveCatalogAttributesRequest], + catalog_service.BatchRemoveCatalogAttributesResponse]: + # 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._BatchRemoveCatalogAttributes(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_attributes_config(self) -> Callable[ + [catalog_service.GetAttributesConfigRequest], + catalog.AttributesConfig]: + # 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._GetAttributesConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_completion_config(self) -> Callable[ + [catalog_service.GetCompletionConfigRequest], + catalog.CompletionConfig]: + # 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._GetCompletionConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_default_branch(self) -> Callable[ + [catalog_service.GetDefaultBranchRequest], + catalog_service.GetDefaultBranchResponse]: + # 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._GetDefaultBranch(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_catalogs(self) -> Callable[ + [catalog_service.ListCatalogsRequest], + catalog_service.ListCatalogsResponse]: + # 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._ListCatalogs(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_catalog_attribute(self) -> Callable[ + [catalog_service.RemoveCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._RemoveCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def replace_catalog_attribute(self) -> Callable[ + [catalog_service.ReplaceCatalogAttributeRequest], + catalog.AttributesConfig]: + # 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._ReplaceCatalogAttribute(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_default_branch(self) -> Callable[ + [catalog_service.SetDefaultBranchRequest], + 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._SetDefaultBranch(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_attributes_config(self) -> Callable[ + [catalog_service.UpdateAttributesConfigRequest], + catalog.AttributesConfig]: + # 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._UpdateAttributesConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_catalog(self) -> Callable[ + [catalog_service.UpdateCatalogRequest], + gcr_catalog.Catalog]: + # 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._UpdateCatalog(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_completion_config(self) -> Callable[ + [catalog_service.UpdateCompletionConfigRequest], + catalog.CompletionConfig]: + # 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._UpdateCompletionConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(CatalogServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(CatalogServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'CatalogServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/__init__.py new file mode 100644 index 00000000..440cbfb4 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/__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 CompletionServiceClient +from .async_client import CompletionServiceAsyncClient + +__all__ = ( + 'CompletionServiceClient', + 'CompletionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/async_client.py new file mode 100644 index 00000000..5e74bce1 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/async_client.py @@ -0,0 +1,507 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import completion_service +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .client import CompletionServiceClient + + +class CompletionServiceAsyncClient: + """Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + _client: CompletionServiceClient + + DEFAULT_ENDPOINT = CompletionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = CompletionServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(CompletionServiceClient.catalog_path) + parse_catalog_path = staticmethod(CompletionServiceClient.parse_catalog_path) + common_billing_account_path = staticmethod(CompletionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(CompletionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(CompletionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(CompletionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(CompletionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(CompletionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(CompletionServiceClient.common_project_path) + parse_common_project_path = staticmethod(CompletionServiceClient.parse_common_project_path) + common_location_path = staticmethod(CompletionServiceClient.common_location_path) + parse_common_location_path = staticmethod(CompletionServiceClient.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: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_info.__func__(CompletionServiceAsyncClient, 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: + CompletionServiceAsyncClient: The constructed client. + """ + return CompletionServiceClient.from_service_account_file.__func__(CompletionServiceAsyncClient, 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 CompletionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(CompletionServiceClient).get_transport_class, type(CompletionServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, CompletionServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service 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, ~.CompletionServiceTransport]): 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 = CompletionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def complete_query(self, + request: Optional[Union[completion_service.CompleteQueryRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> completion_service.CompleteQueryResponse: + r"""Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2beta + + async def sample_complete_query(): + # Create a client + client = retail_v2beta.CompletionServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = await client.complete_query(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.CompleteQueryRequest, dict]]): + The request object. Autocomplete parameters. + 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.retail_v2beta.types.CompleteQueryResponse: + Response of the autocomplete query. + """ + # Create or coerce a protobuf request object. + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.complete_query, + 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(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def import_completion_data(self, + request: Optional[Union[import_config.ImportCompletionDataRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2beta + + async def sample_import_completion_data(): + # Create a client + client = retail_v2beta.CompletionServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2beta.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2beta.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ImportCompletionDataRequest, dict]]): + The request object. Request message for + ImportCompletionData methods. + 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.retail_v2beta.types.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2beta.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportCompletionDataRequest(request) + + # 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_completion_data, + 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, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "CompletionServiceAsyncClient": + 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__ = ( + "CompletionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/client.py new file mode 100644 index 00000000..205c9aff --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/client.py @@ -0,0 +1,716 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import completion_service +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import CompletionServiceGrpcTransport +from .transports.grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .transports.rest import CompletionServiceRestTransport + + +class CompletionServiceClientMeta(type): + """Metaclass for the CompletionService 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[CompletionServiceTransport]] + _transport_registry["grpc"] = CompletionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = CompletionServiceGrpcAsyncIOTransport + _transport_registry["rest"] = CompletionServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[CompletionServiceTransport]: + """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 CompletionServiceClient(metaclass=CompletionServiceClientMeta): + """Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + @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 = "retail.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: + CompletionServiceClient: 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: + CompletionServiceClient: 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) -> CompletionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + CompletionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?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, CompletionServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the completion service 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, CompletionServiceTransport]): 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, CompletionServiceTransport): + # transport is a CompletionServiceTransport 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 complete_query(self, + request: Optional[Union[completion_service.CompleteQueryRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> completion_service.CompleteQueryResponse: + r"""Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2beta + + def sample_complete_query(): + # Create a client + client = retail_v2beta.CompletionServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = client.complete_query(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.CompleteQueryRequest, dict]): + The request object. Autocomplete parameters. + 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.retail_v2beta.types.CompleteQueryResponse: + Response of the autocomplete query. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a completion_service.CompleteQueryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, completion_service.CompleteQueryRequest): + request = completion_service.CompleteQueryRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.complete_query] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("catalog", request.catalog), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def import_completion_data(self, + request: Optional[Union[import_config.ImportCompletionDataRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2beta + + def sample_import_completion_data(): + # Create a client + client = retail_v2beta.CompletionServiceClient() + + # Initialize request argument(s) + input_config = retail_v2beta.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2beta.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ImportCompletionDataRequest, dict]): + The request object. Request message for + ImportCompletionData methods. + 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.retail_v2beta.types.ImportCompletionDataResponse` Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2beta.ImportCompletionDataRequest]. + If the long running operation is done, this message + is returned by the + google.longrunning.Operations.response field if the + operation is successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportCompletionDataRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportCompletionDataRequest): + request = import_config.ImportCompletionDataRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_completion_data] + + # 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, + import_config.ImportCompletionDataResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "CompletionServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "CompletionServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/__init__.py new file mode 100644 index 00000000..f32ad441 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/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 CompletionServiceTransport +from .grpc import CompletionServiceGrpcTransport +from .grpc_asyncio import CompletionServiceGrpcAsyncIOTransport +from .rest import CompletionServiceRestTransport +from .rest import CompletionServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[CompletionServiceTransport]] +_transport_registry['grpc'] = CompletionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = CompletionServiceGrpcAsyncIOTransport +_transport_registry['rest'] = CompletionServiceRestTransport + +__all__ = ( + 'CompletionServiceTransport', + 'CompletionServiceGrpcTransport', + 'CompletionServiceGrpcAsyncIOTransport', + 'CompletionServiceRestTransport', + 'CompletionServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/base.py new file mode 100644 index 00000000..2daf912c --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/base.py @@ -0,0 +1,189 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import completion_service +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class CompletionServiceTransport(abc.ABC): + """Abstract transport class for CompletionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.complete_query: gapic_v1.method.wrap_method( + self.complete_query, + default_timeout=None, + client_info=client_info, + ), + self.import_completion_data: gapic_v1.method.wrap_method( + self.import_completion_data, + 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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Union[ + completion_service.CompleteQueryResponse, + Awaitable[completion_service.CompleteQueryResponse] + ]]: + raise NotImplementedError() + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'CompletionServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py new file mode 100644 index 00000000..715ceff9 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc.py @@ -0,0 +1,366 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import completion_service +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO + + +class CompletionServiceGrpcTransport(CompletionServiceTransport): + """gRPC backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + completion_service.CompleteQueryResponse]: + r"""Return a callable for the complete query method over gRPC. + + Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.CompleteQueryRequest], + ~.CompleteQueryResponse]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + operations_pb2.Operation]: + r"""Return a callable for the import completion data method over gRPC. + + Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.ImportCompletionDataRequest], + ~.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_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'CompletionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..5e42e69d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/grpc_asyncio.py @@ -0,0 +1,365 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import completion_service +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from .base import CompletionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import CompletionServiceGrpcTransport + + +class CompletionServiceGrpcAsyncIOTransport(CompletionServiceTransport): + """gRPC AsyncIO backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + Awaitable[completion_service.CompleteQueryResponse]]: + r"""Return a callable for the complete query method over gRPC. + + Completes the specified prefix with keyword + suggestions. + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.CompleteQueryRequest], + Awaitable[~.CompleteQueryResponse]]: + 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 'complete_query' not in self._stubs: + self._stubs['complete_query'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CompletionService/CompleteQuery', + request_serializer=completion_service.CompleteQueryRequest.serialize, + response_deserializer=completion_service.CompleteQueryResponse.deserialize, + ) + return self._stubs['complete_query'] + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import completion data method over gRPC. + + Bulk import of processed completion dataset. + + Request processing is asynchronous. Partial updating is + not supported. + + The operation is successfully finished only after the + imported suggestions are indexed successfully and ready + for serving. The process takes hours. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.ImportCompletionDataRequest], + 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_completion_data' not in self._stubs: + self._stubs['import_completion_data'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.CompletionService/ImportCompletionData', + request_serializer=import_config.ImportCompletionDataRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_completion_data'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'CompletionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/rest.py new file mode 100644 index 00000000..0efc7655 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/completion_service/transports/rest.py @@ -0,0 +1,666 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import completion_service +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore + +from .base import CompletionServiceTransport, 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 CompletionServiceRestInterceptor: + """Interceptor for CompletionService. + + 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 CompletionServiceRestTransport. + + .. code-block:: python + class MyCustomCompletionServiceInterceptor(CompletionServiceRestInterceptor): + def pre_complete_query(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_complete_query(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_completion_data(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_completion_data(self, response): + logging.log(f"Received response: {response}") + return response + + transport = CompletionServiceRestTransport(interceptor=MyCustomCompletionServiceInterceptor()) + client = CompletionServiceClient(transport=transport) + + + """ + def pre_complete_query(self, request: completion_service.CompleteQueryRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[completion_service.CompleteQueryRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for complete_query + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_complete_query(self, response: completion_service.CompleteQueryResponse) -> completion_service.CompleteQueryResponse: + """Post-rpc interceptor for complete_query + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + def pre_import_completion_data(self, request: import_config.ImportCompletionDataRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportCompletionDataRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_completion_data + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_import_completion_data(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_completion_data + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the CompletionService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the CompletionService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class CompletionServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: CompletionServiceRestInterceptor + + +class CompletionServiceRestTransport(CompletionServiceTransport): + """REST backend transport for CompletionService. + + Autocomplete service for retail. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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[CompletionServiceRestInterceptor] = 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 CompletionServiceRestInterceptor() + 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/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="v2beta") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CompleteQuery(CompletionServiceRestStub): + def __hash__(self): + return hash("CompleteQuery") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "query" : "", } + + @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: completion_service.CompleteQueryRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> completion_service.CompleteQueryResponse: + r"""Call the complete query method over HTTP. + + Args: + request (~.completion_service.CompleteQueryRequest): + The request object. Autocomplete parameters. + 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: + ~.completion_service.CompleteQueryResponse: + Response of the autocomplete query. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{catalog=projects/*/locations/*/catalogs/*}:completeQuery', + }, + ] + request, metadata = self._interceptor.pre_complete_query(request, metadata) + pb_request = completion_service.CompleteQueryRequest.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 = completion_service.CompleteQueryResponse() + pb_resp = completion_service.CompleteQueryResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_complete_query(resp) + return resp + + class _ImportCompletionData(CompletionServiceRestStub): + def __hash__(self): + return hash("ImportCompletionData") + + __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: import_config.ImportCompletionDataRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import completion data method over HTTP. + + Args: + request (~.import_config.ImportCompletionDataRequest): + The request object. Request message for + ImportCompletionData methods. + 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': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/completionData:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_completion_data(request, metadata) + pb_request = import_config.ImportCompletionDataRequest.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_completion_data(resp) + return resp + + @property + def complete_query(self) -> Callable[ + [completion_service.CompleteQueryRequest], + completion_service.CompleteQueryResponse]: + # 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._CompleteQuery(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_completion_data(self) -> Callable[ + [import_config.ImportCompletionDataRequest], + 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._ImportCompletionData(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(CompletionServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(CompletionServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'CompletionServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/__init__.py new file mode 100644 index 00000000..b5539469 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/__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 ControlServiceClient +from .async_client import ControlServiceAsyncClient + +__all__ = ( + 'ControlServiceClient', + 'ControlServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/async_client.py new file mode 100644 index 00000000..df8541de --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/async_client.py @@ -0,0 +1,877 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.control_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control as gcr_control +from google.cloud.retail_v2beta.types import control_service +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .client import ControlServiceClient + + +class ControlServiceAsyncClient: + """Service for modifying Control.""" + + _client: ControlServiceClient + + DEFAULT_ENDPOINT = ControlServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ControlServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ControlServiceClient.catalog_path) + parse_catalog_path = staticmethod(ControlServiceClient.parse_catalog_path) + control_path = staticmethod(ControlServiceClient.control_path) + parse_control_path = staticmethod(ControlServiceClient.parse_control_path) + common_billing_account_path = staticmethod(ControlServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ControlServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ControlServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ControlServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ControlServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ControlServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ControlServiceClient.common_project_path) + parse_common_project_path = staticmethod(ControlServiceClient.parse_common_project_path) + common_location_path = staticmethod(ControlServiceClient.common_location_path) + parse_common_location_path = staticmethod(ControlServiceClient.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: + ControlServiceAsyncClient: The constructed client. + """ + return ControlServiceClient.from_service_account_info.__func__(ControlServiceAsyncClient, 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: + ControlServiceAsyncClient: The constructed client. + """ + return ControlServiceClient.from_service_account_file.__func__(ControlServiceAsyncClient, 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 ControlServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ControlServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ControlServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ControlServiceClient).get_transport_class, type(ControlServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ControlServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the control service 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, ~.ControlServiceTransport]): 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 = ControlServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_control(self, + request: Optional[Union[control_service.CreateControlRequest, dict]] = None, + *, + parent: Optional[str] = None, + control: Optional[gcr_control.Control] = None, + control_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_control.Control: + r"""Creates a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2beta + + async def sample_create_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = await client.create_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.CreateControlRequest, dict]]): + The request object. Request for CreateControl method. + parent (:class:`str`): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control (:class:`google.cloud.retail_v2beta.types.Control`): + Required. The Control to create. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control_id (:class:`str`): + Required. The ID to use for the Control, which will + become the final component of the Control's resource + name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``control_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.retail_v2beta.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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, control, control_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 = control_service.CreateControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if control is not None: + request.control = control + if control_id is not None: + request.control_id = control_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_control, + 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, + ) + + # Done; return the response. + return response + + async def delete_control(self, + request: Optional[Union[control_service.DeleteControlRequest, 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"""Deletes a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to delete + does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + async def sample_delete_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteControlRequest( + name="name_value", + ) + + # Make the request + await client.delete_control(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.DeleteControlRequest, dict]]): + The request object. Request for DeleteControl method. + name (:class:`str`): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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 = control_service.DeleteControlRequest(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_control, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_control(self, + request: Optional[Union[control_service.UpdateControlRequest, dict]] = None, + *, + control: Optional[gcr_control.Control] = 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]] = (), + ) -> gcr_control.Control: + r"""Updates a Control. + + [Control][google.cloud.retail.v2beta.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2beta.Control] to update does + not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + async def sample_update_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateControlRequest( + control=control, + ) + + # Make the request + response = await client.update_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.UpdateControlRequest, dict]]): + The request object. Request for UpdateControl method. + control (:class:`google.cloud.retail_v2beta.types.Control`): + Required. The Control to update. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [Control][google.cloud.retail.v2beta.Control] to update. + The following are NOT supported: + + - [Control.name][google.cloud.retail.v2beta.Control.name] + + If not set or empty, all supported fields are updated. + + 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.retail_v2beta.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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([control, 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 = control_service.UpdateControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if control is not None: + request.control = control + 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_control, + 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(( + ("control.name", request.control.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_control(self, + request: Optional[Union[control_service.GetControlRequest, 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]] = (), + ) -> control.Control: + r"""Gets a Control. + + .. 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 retail_v2beta + + async def sample_get_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetControlRequest( + name="name_value", + ) + + # Make the request + response = await client.get_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.GetControlRequest, dict]]): + The request object. Request for GetControl method. + name (:class:`str`): + Required. The resource name of the Control to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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.retail_v2beta.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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 = control_service.GetControlRequest(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_control, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_controls(self, + request: Optional[Union[control_service.ListControlsRequest, 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.ListControlsAsyncPager: + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. + + .. 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 retail_v2beta + + async def sample_list_controls(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ListControlsRequest, dict]]): + The request object. Request for ListControls method. + parent (:class:`str`): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2beta.services.control_service.pagers.ListControlsAsyncPager: + Response for ListControls 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 = control_service.ListControlsRequest(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_controls, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListControlsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ControlServiceAsyncClient": + 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__ = ( + "ControlServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/client.py new file mode 100644 index 00000000..4f16d8ed --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/client.py @@ -0,0 +1,1093 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.control_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control as gcr_control +from google.cloud.retail_v2beta.types import control_service +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ControlServiceGrpcTransport +from .transports.grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .transports.rest import ControlServiceRestTransport + + +class ControlServiceClientMeta(type): + """Metaclass for the ControlService 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[ControlServiceTransport]] + _transport_registry["grpc"] = ControlServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ControlServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ControlServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ControlServiceTransport]: + """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 ControlServiceClient(metaclass=ControlServiceClientMeta): + """Service for modifying Control.""" + + @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 = "retail.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: + ControlServiceClient: 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: + ControlServiceClient: 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) -> ControlServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ControlServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def control_path(project: str,location: str,catalog: str,control: str,) -> str: + """Returns a fully-qualified control string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/controls/{control}".format(project=project, location=location, catalog=catalog, control=control, ) + + @staticmethod + def parse_control_path(path: str) -> Dict[str,str]: + """Parses a control path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/controls/(?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, ControlServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the control service 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, ControlServiceTransport]): 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, ControlServiceTransport): + # transport is a ControlServiceTransport 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_control(self, + request: Optional[Union[control_service.CreateControlRequest, dict]] = None, + *, + parent: Optional[str] = None, + control: Optional[gcr_control.Control] = None, + control_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_control.Control: + r"""Creates a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + .. 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 retail_v2beta + + def sample_create_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = client.create_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.CreateControlRequest, dict]): + The request object. Request for CreateControl method. + parent (str): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control (google.cloud.retail_v2beta.types.Control): + Required. The Control to create. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + control_id (str): + Required. The ID to use for the Control, which will + become the final component of the Control's resource + name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``control_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.retail_v2beta.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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, control, control_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 control_service.CreateControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.CreateControlRequest): + request = control_service.CreateControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if control is not None: + request.control = control + if control_id is not None: + request.control_id = control_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_control] + + # 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_control(self, + request: Optional[Union[control_service.DeleteControlRequest, 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"""Deletes a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to delete + does not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + def sample_delete_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteControlRequest( + name="name_value", + ) + + # Make the request + client.delete_control(request=request) + + Args: + request (Union[google.cloud.retail_v2beta.types.DeleteControlRequest, dict]): + The request object. Request for DeleteControl method. + name (str): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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 control_service.DeleteControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.DeleteControlRequest): + request = control_service.DeleteControlRequest(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_control] + + # 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 update_control(self, + request: Optional[Union[control_service.UpdateControlRequest, dict]] = None, + *, + control: Optional[gcr_control.Control] = 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]] = (), + ) -> gcr_control.Control: + r"""Updates a Control. + + [Control][google.cloud.retail.v2beta.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2beta.Control] to update does + not exist, a NOT_FOUND error is returned. + + .. 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 retail_v2beta + + def sample_update_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateControlRequest( + control=control, + ) + + # Make the request + response = client.update_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateControlRequest, dict]): + The request object. Request for UpdateControl method. + control (google.cloud.retail_v2beta.types.Control): + Required. The Control to update. + This corresponds to the ``control`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Control][google.cloud.retail.v2beta.Control] to update. + The following are NOT supported: + + - [Control.name][google.cloud.retail.v2beta.Control.name] + + If not set or empty, all supported fields are updated. + + 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.retail_v2beta.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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([control, 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 control_service.UpdateControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.UpdateControlRequest): + request = control_service.UpdateControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if control is not None: + request.control = control + 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_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("control.name", request.control.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_control(self, + request: Optional[Union[control_service.GetControlRequest, 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]] = (), + ) -> control.Control: + r"""Gets a Control. + + .. 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 retail_v2beta + + def sample_get_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetControlRequest( + name="name_value", + ) + + # Make the request + response = client.get_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetControlRequest, dict]): + The request object. Request for GetControl method. + name (str): + Required. The resource name of the Control to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_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.retail_v2beta.types.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at + serving time. + + """ + # 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 control_service.GetControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.GetControlRequest): + request = control_service.GetControlRequest(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_control] + + # 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 list_controls(self, + request: Optional[Union[control_service.ListControlsRequest, 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.ListControlsPager: + r"""Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. + + .. 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 retail_v2beta + + def sample_list_controls(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ListControlsRequest, dict]): + The request object. Request for ListControls method. + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2beta.services.control_service.pagers.ListControlsPager: + Response for ListControls 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 control_service.ListControlsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, control_service.ListControlsRequest): + request = control_service.ListControlsRequest(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_controls] + + # 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.ListControlsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ControlServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ControlServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/pagers.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/pagers.py new file mode 100644 index 00000000..44efaef7 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control_service + + +class ListControlsPager: + """A pager for iterating through ``list_controls`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListControlsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``controls`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListControls`` requests and continue to iterate + through the ``controls`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListControlsResponse` + 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[..., control_service.ListControlsResponse], + request: control_service.ListControlsRequest, + response: control_service.ListControlsResponse, + *, + 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.retail_v2beta.types.ListControlsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListControlsResponse): + 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 = control_service.ListControlsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[control_service.ListControlsResponse]: + 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[control.Control]: + for page in self.pages: + yield from page.controls + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListControlsAsyncPager: + """A pager for iterating through ``list_controls`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListControlsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``controls`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListControls`` requests and continue to iterate + through the ``controls`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListControlsResponse` + 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[control_service.ListControlsResponse]], + request: control_service.ListControlsRequest, + response: control_service.ListControlsResponse, + *, + 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.retail_v2beta.types.ListControlsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListControlsResponse): + 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 = control_service.ListControlsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[control_service.ListControlsResponse]: + 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[control.Control]: + async def async_generator(): + async for page in self.pages: + for response in page.controls: + 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/v2beta/google/cloud/retail_v2beta/services/control_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/__init__.py new file mode 100644 index 00000000..103fc931 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/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 ControlServiceTransport +from .grpc import ControlServiceGrpcTransport +from .grpc_asyncio import ControlServiceGrpcAsyncIOTransport +from .rest import ControlServiceRestTransport +from .rest import ControlServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ControlServiceTransport]] +_transport_registry['grpc'] = ControlServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ControlServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ControlServiceRestTransport + +__all__ = ( + 'ControlServiceTransport', + 'ControlServiceGrpcTransport', + 'ControlServiceGrpcAsyncIOTransport', + 'ControlServiceRestTransport', + 'ControlServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/base.py new file mode 100644 index 00000000..d79d8c9d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/base.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. +# +import abc +from typing import Awaitable, Callable, Dict, Optional, Sequence, Union + +from google.cloud.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control as gcr_control +from google.cloud.retail_v2beta.types import control_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 ControlServiceTransport(abc.ABC): + """Abstract transport class for ControlService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_control: gapic_v1.method.wrap_method( + self.create_control, + default_timeout=None, + client_info=client_info, + ), + self.delete_control: gapic_v1.method.wrap_method( + self.delete_control, + default_timeout=None, + client_info=client_info, + ), + self.update_control: gapic_v1.method.wrap_method( + self.update_control, + default_timeout=None, + client_info=client_info, + ), + self.get_control: gapic_v1.method.wrap_method( + self.get_control, + default_timeout=None, + client_info=client_info, + ), + self.list_controls: gapic_v1.method.wrap_method( + self.list_controls, + 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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + Union[ + gcr_control.Control, + Awaitable[gcr_control.Control] + ]]: + raise NotImplementedError() + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + Union[ + gcr_control.Control, + Awaitable[gcr_control.Control] + ]]: + raise NotImplementedError() + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + Union[ + control.Control, + Awaitable[control.Control] + ]]: + raise NotImplementedError() + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + Union[ + control_service.ListControlsResponse, + Awaitable[control_service.ListControlsResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ControlServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc.py new file mode 100644 index 00000000..4fb0ca7f --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc.py @@ -0,0 +1,421 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control as gcr_control +from google.cloud.retail_v2beta.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ControlServiceTransport, DEFAULT_CLIENT_INFO + + +class ControlServiceGrpcTransport(ControlServiceTransport): + """gRPC backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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 = 'retail.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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + gcr_control.Control]: + r"""Return a callable for the create control method over gRPC. + + Creates a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.CreateControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['create_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/CreateControl', + request_serializer=control_service.CreateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['create_control'] + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete control method over gRPC. + + Deletes a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to delete + does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteControlRequest], + ~.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_control' not in self._stubs: + self._stubs['delete_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/DeleteControl', + request_serializer=control_service.DeleteControlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_control'] + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + gcr_control.Control]: + r"""Return a callable for the update control method over gRPC. + + Updates a Control. + + [Control][google.cloud.retail.v2beta.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2beta.Control] to update does + not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.UpdateControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['update_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/UpdateControl', + request_serializer=control_service.UpdateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['update_control'] + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + control.Control]: + r"""Return a callable for the get control method over gRPC. + + Gets a Control. + + Returns: + Callable[[~.GetControlRequest], + ~.Control]: + 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_control' not in self._stubs: + self._stubs['get_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/GetControl', + request_serializer=control_service.GetControlRequest.serialize, + response_deserializer=control.Control.deserialize, + ) + return self._stubs['get_control'] + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + control_service.ListControlsResponse]: + r"""Return a callable for the list controls method over gRPC. + + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. + + Returns: + Callable[[~.ListControlsRequest], + ~.ListControlsResponse]: + 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_controls' not in self._stubs: + self._stubs['list_controls'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/ListControls', + request_serializer=control_service.ListControlsRequest.serialize, + response_deserializer=control_service.ListControlsResponse.deserialize, + ) + return self._stubs['list_controls'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ControlServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..e16bc500 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/grpc_asyncio.py @@ -0,0 +1,420 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control as gcr_control +from google.cloud.retail_v2beta.types import control_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ControlServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ControlServiceGrpcTransport + + +class ControlServiceGrpcAsyncIOTransport(ControlServiceTransport): + """gRPC AsyncIO backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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 = 'retail.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 create_control(self) -> Callable[ + [control_service.CreateControlRequest], + Awaitable[gcr_control.Control]]: + r"""Return a callable for the create control method over gRPC. + + Creates a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to create + already exists, an ALREADY_EXISTS error is returned. + + Returns: + Callable[[~.CreateControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['create_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/CreateControl', + request_serializer=control_service.CreateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['create_control'] + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete control method over gRPC. + + Deletes a Control. + + If the [Control][google.cloud.retail.v2beta.Control] to delete + does not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.DeleteControlRequest], + 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_control' not in self._stubs: + self._stubs['delete_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/DeleteControl', + request_serializer=control_service.DeleteControlRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_control'] + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + Awaitable[gcr_control.Control]]: + r"""Return a callable for the update control method over gRPC. + + Updates a Control. + + [Control][google.cloud.retail.v2beta.Control] cannot be set to a + different oneof field, if so an INVALID_ARGUMENT is returned. If + the [Control][google.cloud.retail.v2beta.Control] to update does + not exist, a NOT_FOUND error is returned. + + Returns: + Callable[[~.UpdateControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['update_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/UpdateControl', + request_serializer=control_service.UpdateControlRequest.serialize, + response_deserializer=gcr_control.Control.deserialize, + ) + return self._stubs['update_control'] + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + Awaitable[control.Control]]: + r"""Return a callable for the get control method over gRPC. + + Gets a Control. + + Returns: + Callable[[~.GetControlRequest], + Awaitable[~.Control]]: + 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_control' not in self._stubs: + self._stubs['get_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/GetControl', + request_serializer=control_service.GetControlRequest.serialize, + response_deserializer=control.Control.deserialize, + ) + return self._stubs['get_control'] + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + Awaitable[control_service.ListControlsResponse]]: + r"""Return a callable for the list controls method over gRPC. + + Lists all Controls by their parent + [Catalog][google.cloud.retail.v2beta.Catalog]. + + Returns: + Callable[[~.ListControlsRequest], + Awaitable[~.ListControlsResponse]]: + 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_controls' not in self._stubs: + self._stubs['list_controls'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ControlService/ListControls', + request_serializer=control_service.ListControlsRequest.serialize, + response_deserializer=control_service.ListControlsResponse.deserialize, + ) + return self._stubs['list_controls'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ControlServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/rest.py new file mode 100644 index 00000000..d819212d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/control_service/transports/rest.py @@ -0,0 +1,930 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control as gcr_control +from google.cloud.retail_v2beta.types import control_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ControlServiceTransport, 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 ControlServiceRestInterceptor: + """Interceptor for ControlService. + + 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 ControlServiceRestTransport. + + .. code-block:: python + class MyCustomControlServiceInterceptor(ControlServiceRestInterceptor): + def pre_create_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_controls(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_controls(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_control(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ControlServiceRestTransport(interceptor=MyCustomControlServiceInterceptor()) + client = ControlServiceClient(transport=transport) + + + """ + def pre_create_control(self, request: control_service.CreateControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.CreateControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_create_control(self, response: gcr_control.Control) -> gcr_control.Control: + """Post-rpc interceptor for create_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_delete_control(self, request: control_service.DeleteControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.DeleteControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def pre_get_control(self, request: control_service.GetControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.GetControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_get_control(self, response: control.Control) -> control.Control: + """Post-rpc interceptor for get_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_list_controls(self, request: control_service.ListControlsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.ListControlsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_controls + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_list_controls(self, response: control_service.ListControlsResponse) -> control_service.ListControlsResponse: + """Post-rpc interceptor for list_controls + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_update_control(self, request: control_service.UpdateControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[control_service.UpdateControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_update_control(self, response: gcr_control.Control) -> gcr_control.Control: + """Post-rpc interceptor for update_control + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ControlService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ControlService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ControlServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ControlServiceRestInterceptor + + +class ControlServiceRestTransport(ControlServiceTransport): + """REST backend transport for ControlService. + + Service for modifying Control. + + 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 = 'retail.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[ControlServiceRestInterceptor] = 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 ControlServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _CreateControl(ControlServiceRestStub): + def __hash__(self): + return hash("CreateControl") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "controlId" : "", } + + @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: control_service.CreateControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_control.Control: + r"""Call the create control method over HTTP. + + Args: + request (~.control_service.CreateControlRequest): + The request object. Request for CreateControl 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: + ~.gcr_control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/controls', + 'body': 'control', + }, + ] + request, metadata = self._interceptor.pre_create_control(request, metadata) + pb_request = control_service.CreateControlRequest.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 = gcr_control.Control() + pb_resp = gcr_control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_control(resp) + return resp + + class _DeleteControl(ControlServiceRestStub): + def __hash__(self): + return hash("DeleteControl") + + __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: control_service.DeleteControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete control method over HTTP. + + Args: + request (~.control_service.DeleteControlRequest): + The request object. Request for DeleteControl 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/controls/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_control(request, metadata) + pb_request = control_service.DeleteControlRequest.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 _GetControl(ControlServiceRestStub): + def __hash__(self): + return hash("GetControl") + + __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: control_service.GetControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> control.Control: + r"""Call the get control method over HTTP. + + Args: + request (~.control_service.GetControlRequest): + The request object. Request for GetControl 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: + ~.control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/controls/*}', + }, + ] + request, metadata = self._interceptor.pre_get_control(request, metadata) + pb_request = control_service.GetControlRequest.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 = control.Control() + pb_resp = control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_control(resp) + return resp + + class _ListControls(ControlServiceRestStub): + def __hash__(self): + return hash("ListControls") + + __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: control_service.ListControlsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> control_service.ListControlsResponse: + r"""Call the list controls method over HTTP. + + Args: + request (~.control_service.ListControlsRequest): + The request object. Request for ListControls 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: + ~.control_service.ListControlsResponse: + Response for ListControls method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/controls', + }, + ] + request, metadata = self._interceptor.pre_list_controls(request, metadata) + pb_request = control_service.ListControlsRequest.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 = control_service.ListControlsResponse() + pb_resp = control_service.ListControlsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_controls(resp) + return resp + + class _UpdateControl(ControlServiceRestStub): + def __hash__(self): + return hash("UpdateControl") + + __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: control_service.UpdateControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_control.Control: + r"""Call the update control method over HTTP. + + Args: + request (~.control_service.UpdateControlRequest): + The request object. Request for UpdateControl 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: + ~.gcr_control.Control: + Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and affect search or recommendation results at serving + time. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2beta/{control.name=projects/*/locations/*/catalogs/*/controls/*}', + 'body': 'control', + }, + ] + request, metadata = self._interceptor.pre_update_control(request, metadata) + pb_request = control_service.UpdateControlRequest.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 = gcr_control.Control() + pb_resp = gcr_control.Control.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_control(resp) + return resp + + @property + def create_control(self) -> Callable[ + [control_service.CreateControlRequest], + gcr_control.Control]: + # 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._CreateControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_control(self) -> Callable[ + [control_service.DeleteControlRequest], + 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._DeleteControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_control(self) -> Callable[ + [control_service.GetControlRequest], + control.Control]: + # 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._GetControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_controls(self) -> Callable[ + [control_service.ListControlsRequest], + control_service.ListControlsResponse]: + # 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._ListControls(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_control(self) -> Callable[ + [control_service.UpdateControlRequest], + gcr_control.Control]: + # 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._UpdateControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ControlServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ControlServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ControlServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/__init__.py new file mode 100644 index 00000000..2c368b92 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/__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 ModelServiceClient +from .async_client import ModelServiceAsyncClient + +__all__ = ( + 'ModelServiceClient', + 'ModelServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/async_client.py new file mode 100644 index 00000000..2c98b85b --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/async_client.py @@ -0,0 +1,1220 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.model_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .client import ModelServiceClient + + +class ModelServiceAsyncClient: + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + _client: ModelServiceClient + + DEFAULT_ENDPOINT = ModelServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ModelServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ModelServiceClient.catalog_path) + parse_catalog_path = staticmethod(ModelServiceClient.parse_catalog_path) + model_path = staticmethod(ModelServiceClient.model_path) + parse_model_path = staticmethod(ModelServiceClient.parse_model_path) + common_billing_account_path = staticmethod(ModelServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ModelServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ModelServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ModelServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ModelServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ModelServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ModelServiceClient.common_project_path) + parse_common_project_path = staticmethod(ModelServiceClient.parse_common_project_path) + common_location_path = staticmethod(ModelServiceClient.common_location_path) + parse_common_location_path = staticmethod(ModelServiceClient.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: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_info.__func__(ModelServiceAsyncClient, 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: + ModelServiceAsyncClient: The constructed client. + """ + return ModelServiceClient.from_service_account_file.__func__(ModelServiceAsyncClient, 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 ModelServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ModelServiceClient).get_transport_class, type(ModelServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ModelServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service 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, ~.ModelServiceTransport]): 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 = ModelServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_model(self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Creates a new model. + + .. 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 retail_v2beta + + async def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.CreateModelRequest, dict]]): + The request object. Request for creating a model. + parent (:class:`str`): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (:class:`google.cloud.retail_v2beta.types.Model`): + Required. The payload of the + [Model][google.cloud.retail.v2beta.Model] to create. + + This corresponds to the ``model`` 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.retail_v2beta.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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, model]) + 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 = model_service.CreateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # 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_model, + 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, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + async def get_model(self, + request: Optional[Union[model_service.GetModelRequest, 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]] = (), + ) -> model.Model: + r"""Gets a model. + + .. 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 retail_v2beta + + async def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.GetModelRequest, dict]]): + The request object. Request for getting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.GetModelRequest(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_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def pause_model(self, + request: Optional[Union[model_service.PauseModelRequest, 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]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. 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 retail_v2beta + + async def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.PauseModelRequest, dict]]): + The request object. Request for pausing training of a + model. + name (:class:`str`): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.PauseModelRequest(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.pause_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def resume_model(self, + request: Optional[Union[model_service.ResumeModelRequest, 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]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. 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 retail_v2beta + + async def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ResumeModelRequest, dict]]): + The request object. Request for resuming training of a + model. + name (:class:`str`): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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 = model_service.ResumeModelRequest(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.resume_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def delete_model(self, + request: Optional[Union[model_service.DeleteModelRequest, 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"""Deletes an existing model. + + .. 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 retail_v2beta + + async def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.DeleteModelRequest, dict]]): + The request object. Request for deleting a model. + name (:class:`str`): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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 = model_service.DeleteModelRequest(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_model, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def list_models(self, + request: Optional[Union[model_service.ListModelsRequest, 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.ListModelsAsyncPager: + r"""Lists all the models linked to this event store. + + .. 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 retail_v2beta + + async def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ListModelsRequest, dict]]): + The request object. Request for listing models associated + with a resource. + parent (:class:`str`): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2beta.services.model_service.pagers.ListModelsAsyncPager: + Response to a ListModelRequest. + + 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 = model_service.ListModelsRequest(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_models, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListModelsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def update_model(self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = 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]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. 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 retail_v2beta + + async def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.UpdateModelRequest, dict]]): + The request object. Request for updating an existing + model. + model (:class:`google.cloud.retail_v2beta.types.Model`): + Required. The body of the updated + [Model][google.cloud.retail.v2beta.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + 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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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([model, 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 = model_service.UpdateModelRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + 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_model, + 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(( + ("model.name", request.model.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def tune_model(self, + request: Optional[Union[model_service.TuneModelRequest, 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]] = (), + ) -> operation_async.AsyncOperation: + r"""Tunes an existing model. + + .. 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 retail_v2beta + + async def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.TuneModelRequest, dict]]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (:class:`str`): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2beta.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # 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 = model_service.TuneModelRequest(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.tune_model, + 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(( + ("name", request.name), + )), + ) + + # 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, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ModelServiceAsyncClient": + 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__ = ( + "ModelServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/client.py new file mode 100644 index 00000000..4148ce54 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/client.py @@ -0,0 +1,1436 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.model_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ModelServiceGrpcTransport +from .transports.grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .transports.rest import ModelServiceRestTransport + + +class ModelServiceClientMeta(type): + """Metaclass for the ModelService 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[ModelServiceTransport]] + _transport_registry["grpc"] = ModelServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ModelServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ModelServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ModelServiceTransport]: + """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 ModelServiceClient(metaclass=ModelServiceClientMeta): + """Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + """ + + @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 = "retail.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: + ModelServiceClient: 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: + ModelServiceClient: 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) -> ModelServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ModelServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def model_path(project: str,location: str,catalog: str,model: str,) -> str: + """Returns a fully-qualified model string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format(project=project, location=location, catalog=catalog, model=model, ) + + @staticmethod + def parse_model_path(path: str) -> Dict[str,str]: + """Parses a model path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/models/(?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, ModelServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the model service 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, ModelServiceTransport]): 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, ModelServiceTransport): + # transport is a ModelServiceTransport 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_model(self, + request: Optional[Union[model_service.CreateModelRequest, dict]] = None, + *, + parent: Optional[str] = None, + model: Optional[gcr_model.Model] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Creates a new model. + + .. 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 retail_v2beta + + def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.CreateModelRequest, dict]): + The request object. Request for creating a model. + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + model (google.cloud.retail_v2beta.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2beta.Model] to create. + + This corresponds to the ``model`` 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.retail_v2beta.types.Model` Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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, model]) + 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 model_service.CreateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.CreateModelRequest): + request = model_service.CreateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if model is not None: + request.model = model + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_model] + + # 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, + gcr_model.Model, + metadata_type=model_service.CreateModelMetadata, + ) + + # Done; return the response. + return response + + def get_model(self, + request: Optional[Union[model_service.GetModelRequest, 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]] = (), + ) -> model.Model: + r"""Gets a model. + + .. 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 retail_v2beta + + def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetModelRequest, dict]): + The request object. Request for getting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.GetModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.GetModelRequest): + request = model_service.GetModelRequest(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_model] + + # 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 pause_model(self, + request: Optional[Union[model_service.PauseModelRequest, 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]] = (), + ) -> model.Model: + r"""Pauses the training of an existing model. + + .. 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 retail_v2beta + + def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.PauseModelRequest, dict]): + The request object. Request for pausing training of a + model. + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.PauseModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.PauseModelRequest): + request = model_service.PauseModelRequest(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.pause_model] + + # 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 resume_model(self, + request: Optional[Union[model_service.ResumeModelRequest, 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]] = (), + ) -> model.Model: + r"""Resumes the training of an existing model. + + .. 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 retail_v2beta + + def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ResumeModelRequest, dict]): + The request object. Request for resuming training of a + model. + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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 model_service.ResumeModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ResumeModelRequest): + request = model_service.ResumeModelRequest(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.resume_model] + + # 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 delete_model(self, + request: Optional[Union[model_service.DeleteModelRequest, 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"""Deletes an existing model. + + .. 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 retail_v2beta + + def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + Args: + request (Union[google.cloud.retail_v2beta.types.DeleteModelRequest, dict]): + The request object. Request for deleting a model. + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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 model_service.DeleteModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.DeleteModelRequest): + request = model_service.DeleteModelRequest(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_model] + + # 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_models(self, + request: Optional[Union[model_service.ListModelsRequest, 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.ListModelsPager: + r"""Lists all the models linked to this event store. + + .. 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 retail_v2beta + + def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ListModelsRequest, dict]): + The request object. Request for listing models associated + with a resource. + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2beta.services.model_service.pagers.ListModelsPager: + Response to a ListModelRequest. + + 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 model_service.ListModelsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.ListModelsRequest): + request = model_service.ListModelsRequest(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_models] + + # 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.ListModelsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def update_model(self, + request: Optional[Union[model_service.UpdateModelRequest, dict]] = None, + *, + model: Optional[gcr_model.Model] = 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]] = (), + ) -> gcr_model.Model: + r"""Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + .. 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 retail_v2beta + + def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateModelRequest, dict]): + The request object. Request for updating an existing + model. + model (google.cloud.retail_v2beta.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2beta.Model]. + + This corresponds to the ``model`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in + the provided 'model' to update. If not + set, by default updates all fields. + + 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.retail_v2beta.types.Model: + Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + # 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([model, 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 model_service.UpdateModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.UpdateModelRequest): + request = model_service.UpdateModelRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if model is not None: + request.model = model + 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_model] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("model.name", request.model.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def tune_model(self, + request: Optional[Union[model_service.TuneModelRequest, 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]] = (), + ) -> operation.Operation: + r"""Tunes an existing model. + + .. 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 retail_v2beta + + def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.TuneModelRequest, dict]): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + name (str): + Required. The resource name of the model to tune. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_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.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2beta.types.TuneModelResponse` + Response associated with a tune operation. + + """ + # 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 model_service.TuneModelRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, model_service.TuneModelRequest): + request = model_service.TuneModelRequest(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.tune_model] + + # 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, + ) + + # Wrap the response in an operation future. + response = operation.from_gapic( + response, + self._transport.operations_client, + model_service.TuneModelResponse, + metadata_type=model_service.TuneModelMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ModelServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ModelServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/pagers.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/pagers.py new file mode 100644 index 00000000..69519cfa --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model_service + + +class ListModelsPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListModelsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListModelsResponse` + 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[..., model_service.ListModelsResponse], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + 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.retail_v2beta.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListModelsResponse): + 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 = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[model_service.ListModelsResponse]: + 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[model.Model]: + for page in self.pages: + yield from page.models + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListModelsAsyncPager: + """A pager for iterating through ``list_models`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListModelsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``models`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListModels`` requests and continue to iterate + through the ``models`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListModelsResponse` + 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[model_service.ListModelsResponse]], + request: model_service.ListModelsRequest, + response: model_service.ListModelsResponse, + *, + 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.retail_v2beta.types.ListModelsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListModelsResponse): + 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 = model_service.ListModelsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[model_service.ListModelsResponse]: + 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[model.Model]: + async def async_generator(): + async for page in self.pages: + for response in page.models: + 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/v2beta/google/cloud/retail_v2beta/services/model_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/__init__.py new file mode 100644 index 00000000..c51cadf4 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/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 ModelServiceTransport +from .grpc import ModelServiceGrpcTransport +from .grpc_asyncio import ModelServiceGrpcAsyncIOTransport +from .rest import ModelServiceRestTransport +from .rest import ModelServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ModelServiceTransport]] +_transport_registry['grpc'] = ModelServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ModelServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ModelServiceRestTransport + +__all__ = ( + 'ModelServiceTransport', + 'ModelServiceGrpcTransport', + 'ModelServiceGrpcAsyncIOTransport', + 'ModelServiceRestTransport', + 'ModelServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/base.py new file mode 100644 index 00000000..db3dac96 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/base.py @@ -0,0 +1,275 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_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 ModelServiceTransport(abc.ABC): + """Abstract transport class for ModelService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_model: gapic_v1.method.wrap_method( + self.create_model, + default_timeout=None, + client_info=client_info, + ), + self.get_model: gapic_v1.method.wrap_method( + self.get_model, + default_timeout=None, + client_info=client_info, + ), + self.pause_model: gapic_v1.method.wrap_method( + self.pause_model, + default_timeout=None, + client_info=client_info, + ), + self.resume_model: gapic_v1.method.wrap_method( + self.resume_model, + default_timeout=None, + client_info=client_info, + ), + self.delete_model: gapic_v1.method.wrap_method( + self.delete_model, + default_timeout=None, + client_info=client_info, + ), + self.list_models: gapic_v1.method.wrap_method( + self.list_models, + default_timeout=None, + client_info=client_info, + ), + self.update_model: gapic_v1.method.wrap_method( + self.update_model, + default_timeout=None, + client_info=client_info, + ), + self.tune_model: gapic_v1.method.wrap_method( + self.tune_model, + 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_model(self) -> Callable[ + [model_service.CreateModelRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + Union[ + model.Model, + Awaitable[model.Model] + ]]: + raise NotImplementedError() + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + Union[ + model_service.ListModelsResponse, + Awaitable[model_service.ListModelsResponse] + ]]: + raise NotImplementedError() + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + Union[ + gcr_model.Model, + Awaitable[gcr_model.Model] + ]]: + raise NotImplementedError() + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ModelServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc.py new file mode 100644 index 00000000..c704cea2 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc.py @@ -0,0 +1,518 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ModelServiceTransport, DEFAULT_CLIENT_INFO + + +class ModelServiceGrpcTransport(ModelServiceTransport): + """gRPC backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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 = 'retail.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_model(self) -> Callable[ + [model_service.CreateModelRequest], + operations_pb2.Operation]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + ~.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 'create_model' not in self._stubs: + self._stubs['create_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/CreateModel', + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_model'] + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + model.Model]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + ~.Model]: + 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_model' not in self._stubs: + self._stubs['get_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/GetModel', + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['get_model'] + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + model.Model]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + ~.Model]: + 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 'pause_model' not in self._stubs: + self._stubs['pause_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/PauseModel', + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['pause_model'] + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + model.Model]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + ~.Model]: + 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 'resume_model' not in self._stubs: + self._stubs['resume_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/ResumeModel', + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['resume_model'] + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + ~.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_model' not in self._stubs: + self._stubs['delete_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/DeleteModel', + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_model'] + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + model_service.ListModelsResponse]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + ~.ListModelsResponse]: + 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_models' not in self._stubs: + self._stubs['list_models'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/ListModels', + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs['list_models'] + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + gcr_model.Model]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + ~.Model]: + 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_model' not in self._stubs: + self._stubs['update_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/UpdateModel', + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs['update_model'] + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + operations_pb2.Operation]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + ~.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 'tune_model' not in self._stubs: + self._stubs['tune_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/TuneModel', + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['tune_model'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ModelServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..ccd24dd7 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/grpc_asyncio.py @@ -0,0 +1,517 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ModelServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ModelServiceGrpcTransport + + +class ModelServiceGrpcAsyncIOTransport(ModelServiceTransport): + """gRPC AsyncIO backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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 = 'retail.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_model(self) -> Callable[ + [model_service.CreateModelRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the create model method over gRPC. + + Creates a new model. + + Returns: + Callable[[~.CreateModelRequest], + 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 'create_model' not in self._stubs: + self._stubs['create_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/CreateModel', + request_serializer=model_service.CreateModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['create_model'] + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the get model method over gRPC. + + Gets a model. + + Returns: + Callable[[~.GetModelRequest], + Awaitable[~.Model]]: + 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_model' not in self._stubs: + self._stubs['get_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/GetModel', + request_serializer=model_service.GetModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['get_model'] + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the pause model method over gRPC. + + Pauses the training of an existing model. + + Returns: + Callable[[~.PauseModelRequest], + Awaitable[~.Model]]: + 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 'pause_model' not in self._stubs: + self._stubs['pause_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/PauseModel', + request_serializer=model_service.PauseModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['pause_model'] + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + Awaitable[model.Model]]: + r"""Return a callable for the resume model method over gRPC. + + Resumes the training of an existing model. + + Returns: + Callable[[~.ResumeModelRequest], + Awaitable[~.Model]]: + 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 'resume_model' not in self._stubs: + self._stubs['resume_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/ResumeModel', + request_serializer=model_service.ResumeModelRequest.serialize, + response_deserializer=model.Model.deserialize, + ) + return self._stubs['resume_model'] + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete model method over gRPC. + + Deletes an existing model. + + Returns: + Callable[[~.DeleteModelRequest], + 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_model' not in self._stubs: + self._stubs['delete_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/DeleteModel', + request_serializer=model_service.DeleteModelRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_model'] + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + Awaitable[model_service.ListModelsResponse]]: + r"""Return a callable for the list models method over gRPC. + + Lists all the models linked to this event store. + + Returns: + Callable[[~.ListModelsRequest], + Awaitable[~.ListModelsResponse]]: + 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_models' not in self._stubs: + self._stubs['list_models'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/ListModels', + request_serializer=model_service.ListModelsRequest.serialize, + response_deserializer=model_service.ListModelsResponse.deserialize, + ) + return self._stubs['list_models'] + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + Awaitable[gcr_model.Model]]: + r"""Return a callable for the update model method over gRPC. + + Update of model metadata. Only fields that currently can be + updated are: ``filtering_option`` and ``periodic_tuning_state``. + If other values are provided, this API method ignores them. + + Returns: + Callable[[~.UpdateModelRequest], + Awaitable[~.Model]]: + 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_model' not in self._stubs: + self._stubs['update_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/UpdateModel', + request_serializer=model_service.UpdateModelRequest.serialize, + response_deserializer=gcr_model.Model.deserialize, + ) + return self._stubs['update_model'] + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the tune model method over gRPC. + + Tunes an existing model. + + Returns: + Callable[[~.TuneModelRequest], + 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 'tune_model' not in self._stubs: + self._stubs['tune_model'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ModelService/TuneModel', + request_serializer=model_service.TuneModelRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['tune_model'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ModelServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/rest.py new file mode 100644 index 00000000..9e7418f0 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/model_service/transports/rest.py @@ -0,0 +1,1382 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ModelServiceTransport, 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 ModelServiceRestInterceptor: + """Interceptor for ModelService. + + 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 ModelServiceRestTransport. + + .. code-block:: python + class MyCustomModelServiceInterceptor(ModelServiceRestInterceptor): + def pre_create_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_models(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_models(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_pause_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_pause_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_resume_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_resume_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_tune_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_tune_model(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_model(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_model(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ModelServiceRestTransport(interceptor=MyCustomModelServiceInterceptor()) + client = ModelServiceClient(transport=transport) + + + """ + def pre_create_model(self, request: model_service.CreateModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.CreateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_create_model(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for create_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_delete_model(self, request: model_service.DeleteModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.DeleteModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def pre_get_model(self, request: model_service.GetModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.GetModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for get_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_models(self, request: model_service.ListModelsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.ListModelsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_models + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_models(self, response: model_service.ListModelsResponse) -> model_service.ListModelsResponse: + """Post-rpc interceptor for list_models + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_pause_model(self, request: model_service.PauseModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.PauseModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for pause_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_pause_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for pause_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_resume_model(self, request: model_service.ResumeModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.ResumeModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for resume_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_resume_model(self, response: model.Model) -> model.Model: + """Post-rpc interceptor for resume_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_tune_model(self, request: model_service.TuneModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.TuneModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for tune_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_tune_model(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for tune_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_update_model(self, request: model_service.UpdateModelRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[model_service.UpdateModelRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_model + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_update_model(self, response: gcr_model.Model) -> gcr_model.Model: + """Post-rpc interceptor for update_model + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ModelService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ModelService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ModelServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ModelServiceRestInterceptor + + +class ModelServiceRestTransport(ModelServiceTransport): + """REST backend transport for ModelService. + + Service for performing CRUD operations on models. Recommendation + models contain all the metadata necessary to generate a set of + models for the ``Predict()`` API. A model is queried indirectly via + a ServingConfig, which associates a model with a given Placement + (e.g. Frequently Bought Together on Home Page). + + This service allows you to do the following: + + - Initiate training of a model. + - Pause training of an existing model. + - List all the available models along with their metadata. + - Control their tuning schedule. + + 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 = 'retail.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[ModelServiceRestInterceptor] = 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 ModelServiceRestInterceptor() + 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/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="v2beta") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CreateModel(ModelServiceRestStub): + def __hash__(self): + return hash("CreateModel") + + __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: model_service.CreateModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the create model method over HTTP. + + Args: + request (~.model_service.CreateModelRequest): + The request object. Request for creating a model. + 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': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/models', + 'body': 'model', + }, + ] + request, metadata = self._interceptor.pre_create_model(request, metadata) + pb_request = model_service.CreateModelRequest.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_create_model(resp) + return resp + + class _DeleteModel(ModelServiceRestStub): + def __hash__(self): + return hash("DeleteModel") + + __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: model_service.DeleteModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete model method over HTTP. + + Args: + request (~.model_service.DeleteModelRequest): + The request object. Request for deleting a model. + 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_model(request, metadata) + pb_request = model_service.DeleteModelRequest.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 _GetModel(ModelServiceRestStub): + def __hash__(self): + return hash("GetModel") + + __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: model_service.GetModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the get model method over HTTP. + + Args: + request (~.model_service.GetModelRequest): + The request object. Request for getting a model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}', + }, + ] + request, metadata = self._interceptor.pre_get_model(request, metadata) + pb_request = model_service.GetModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_model(resp) + return resp + + class _ListModels(ModelServiceRestStub): + def __hash__(self): + return hash("ListModels") + + __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: model_service.ListModelsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model_service.ListModelsResponse: + r"""Call the list models method over HTTP. + + Args: + request (~.model_service.ListModelsRequest): + The request object. Request for listing models associated + with a resource. + 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: + ~.model_service.ListModelsResponse: + Response to a ListModelRequest. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/models', + }, + ] + request, metadata = self._interceptor.pre_list_models(request, metadata) + pb_request = model_service.ListModelsRequest.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 = model_service.ListModelsResponse() + pb_resp = model_service.ListModelsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_models(resp) + return resp + + class _PauseModel(ModelServiceRestStub): + def __hash__(self): + return hash("PauseModel") + + __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: model_service.PauseModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the pause model method over HTTP. + + Args: + request (~.model_service.PauseModelRequest): + The request object. Request for pausing training of a + model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}:pause', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_pause_model(request, metadata) + pb_request = model_service.PauseModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_pause_model(resp) + return resp + + class _ResumeModel(ModelServiceRestStub): + def __hash__(self): + return hash("ResumeModel") + + __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: model_service.ResumeModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> model.Model: + r"""Call the resume model method over HTTP. + + Args: + request (~.model_service.ResumeModelRequest): + The request object. Request for resuming training of a + model. + 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: + ~.model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}:resume', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_resume_model(request, metadata) + pb_request = model_service.ResumeModelRequest.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 = model.Model() + pb_resp = model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_resume_model(resp) + return resp + + class _TuneModel(ModelServiceRestStub): + def __hash__(self): + return hash("TuneModel") + + __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: model_service.TuneModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the tune model method over HTTP. + + Args: + request (~.model_service.TuneModelRequest): + The request object. Request to manually start a tuning + process now (instead of waiting for the + periodically scheduled tuning to + happen). + 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}:tune', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_tune_model(request, metadata) + pb_request = model_service.TuneModelRequest.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_tune_model(resp) + return resp + + class _UpdateModel(ModelServiceRestStub): + def __hash__(self): + return hash("UpdateModel") + + __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: model_service.UpdateModelRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_model.Model: + r"""Call the update model method over HTTP. + + Args: + request (~.model_service.UpdateModelRequest): + The request object. Request for updating an existing + model. + 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: + ~.gcr_model.Model: + Metadata that describes the training and serving + parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be + associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + and then queried through the Predict API. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2beta/{model.name=projects/*/locations/*/catalogs/*/models/*}', + 'body': 'model', + }, + ] + request, metadata = self._interceptor.pre_update_model(request, metadata) + pb_request = model_service.UpdateModelRequest.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 = gcr_model.Model() + pb_resp = gcr_model.Model.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_model(resp) + return resp + + @property + def create_model(self) -> Callable[ + [model_service.CreateModelRequest], + 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._CreateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_model(self) -> Callable[ + [model_service.DeleteModelRequest], + 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._DeleteModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_model(self) -> Callable[ + [model_service.GetModelRequest], + model.Model]: + # 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._GetModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_models(self) -> Callable[ + [model_service.ListModelsRequest], + model_service.ListModelsResponse]: + # 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._ListModels(self._session, self._host, self._interceptor) # type: ignore + + @property + def pause_model(self) -> Callable[ + [model_service.PauseModelRequest], + model.Model]: + # 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._PauseModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def resume_model(self) -> Callable[ + [model_service.ResumeModelRequest], + model.Model]: + # 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._ResumeModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def tune_model(self) -> Callable[ + [model_service.TuneModelRequest], + 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._TuneModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_model(self) -> Callable[ + [model_service.UpdateModelRequest], + gcr_model.Model]: + # 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._UpdateModel(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ModelServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ModelServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ModelServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/__init__.py new file mode 100644 index 00000000..905b8c43 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/__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 PredictionServiceClient +from .async_client import PredictionServiceAsyncClient + +__all__ = ( + 'PredictionServiceClient', + 'PredictionServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/async_client.py new file mode 100644 index 00000000..5d2b1713 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/async_client.py @@ -0,0 +1,384 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .client import PredictionServiceClient + + +class PredictionServiceAsyncClient: + """Service for making recommendation prediction.""" + + _client: PredictionServiceClient + + DEFAULT_ENDPOINT = PredictionServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = PredictionServiceClient.DEFAULT_MTLS_ENDPOINT + + product_path = staticmethod(PredictionServiceClient.product_path) + parse_product_path = staticmethod(PredictionServiceClient.parse_product_path) + common_billing_account_path = staticmethod(PredictionServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(PredictionServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(PredictionServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(PredictionServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(PredictionServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(PredictionServiceClient.parse_common_organization_path) + common_project_path = staticmethod(PredictionServiceClient.common_project_path) + parse_common_project_path = staticmethod(PredictionServiceClient.parse_common_project_path) + common_location_path = staticmethod(PredictionServiceClient.common_location_path) + parse_common_location_path = staticmethod(PredictionServiceClient.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: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_info.__func__(PredictionServiceAsyncClient, 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: + PredictionServiceAsyncClient: The constructed client. + """ + return PredictionServiceClient.from_service_account_file.__func__(PredictionServiceAsyncClient, 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 PredictionServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(PredictionServiceClient).get_transport_class, type(PredictionServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, PredictionServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service 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, ~.PredictionServiceTransport]): 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 = PredictionServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def predict(self, + request: Optional[Union[prediction_service.PredictRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + .. 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 retail_v2beta + + async def sample_predict(): + # Create a client + client = retail_v2beta.PredictionServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = await client.predict(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.PredictRequest, dict]]): + The request object. Request message for Predict 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: + google.cloud.retail_v2beta.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.predict, + 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(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "PredictionServiceAsyncClient": + 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__ = ( + "PredictionServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/client.py new file mode 100644 index 00000000..056b8d7b --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/client.py @@ -0,0 +1,592 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import PredictionServiceGrpcTransport +from .transports.grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .transports.rest import PredictionServiceRestTransport + + +class PredictionServiceClientMeta(type): + """Metaclass for the PredictionService 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[PredictionServiceTransport]] + _transport_registry["grpc"] = PredictionServiceGrpcTransport + _transport_registry["grpc_asyncio"] = PredictionServiceGrpcAsyncIOTransport + _transport_registry["rest"] = PredictionServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[PredictionServiceTransport]: + """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 PredictionServiceClient(metaclass=PredictionServiceClientMeta): + """Service for making recommendation prediction.""" + + @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 = "retail.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: + PredictionServiceClient: 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: + PredictionServiceClient: 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) -> PredictionServiceTransport: + """Returns the transport used by the client instance. + + Returns: + PredictionServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, PredictionServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the prediction service 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, PredictionServiceTransport]): 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, PredictionServiceTransport): + # transport is a PredictionServiceTransport 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 predict(self, + request: Optional[Union[prediction_service.PredictRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> prediction_service.PredictResponse: + r"""Makes a recommendation prediction. + + .. 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 retail_v2beta + + def sample_predict(): + # Create a client + client = retail_v2beta.PredictionServiceClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = client.predict(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.PredictRequest, dict]): + The request object. Request message for Predict 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: + google.cloud.retail_v2beta.types.PredictResponse: + Response message for predict method. + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a prediction_service.PredictRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, prediction_service.PredictRequest): + request = prediction_service.PredictRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.predict] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "PredictionServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "PredictionServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/__init__.py new file mode 100644 index 00000000..d8c81688 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/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 PredictionServiceTransport +from .grpc import PredictionServiceGrpcTransport +from .grpc_asyncio import PredictionServiceGrpcAsyncIOTransport +from .rest import PredictionServiceRestTransport +from .rest import PredictionServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[PredictionServiceTransport]] +_transport_registry['grpc'] = PredictionServiceGrpcTransport +_transport_registry['grpc_asyncio'] = PredictionServiceGrpcAsyncIOTransport +_transport_registry['rest'] = PredictionServiceRestTransport + +__all__ = ( + 'PredictionServiceTransport', + 'PredictionServiceGrpcTransport', + 'PredictionServiceGrpcAsyncIOTransport', + 'PredictionServiceRestTransport', + 'PredictionServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/base.py new file mode 100644 index 00000000..eb63bff1 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/base.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class PredictionServiceTransport(abc.ABC): + """Abstract transport class for PredictionService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.predict: gapic_v1.method.wrap_method( + self.predict, + 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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + Union[ + prediction_service.PredictResponse, + Awaitable[prediction_service.PredictResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'PredictionServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc.py new file mode 100644 index 00000000..1f01803d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc.py @@ -0,0 +1,302 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO + + +class PredictionServiceGrpcTransport(PredictionServiceTransport): + """gRPC backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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 = 'retail.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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + prediction_service.PredictResponse]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + ~.PredictResponse]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'PredictionServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..d27fc7d7 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/grpc_asyncio.py @@ -0,0 +1,301 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore +from .base import PredictionServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import PredictionServiceGrpcTransport + + +class PredictionServiceGrpcAsyncIOTransport(PredictionServiceTransport): + """gRPC AsyncIO backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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 = 'retail.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 predict(self) -> Callable[ + [prediction_service.PredictRequest], + Awaitable[prediction_service.PredictResponse]]: + r"""Return a callable for the predict method over gRPC. + + Makes a recommendation prediction. + + Returns: + Callable[[~.PredictRequest], + Awaitable[~.PredictResponse]]: + 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 'predict' not in self._stubs: + self._stubs['predict'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.PredictionService/Predict', + request_serializer=prediction_service.PredictRequest.serialize, + response_deserializer=prediction_service.PredictResponse.deserialize, + ) + return self._stubs['predict'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'PredictionServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/rest.py new file mode 100644 index 00000000..39eaeabd --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/prediction_service/transports/rest.py @@ -0,0 +1,495 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import prediction_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import PredictionServiceTransport, 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 PredictionServiceRestInterceptor: + """Interceptor for PredictionService. + + 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 PredictionServiceRestTransport. + + .. code-block:: python + class MyCustomPredictionServiceInterceptor(PredictionServiceRestInterceptor): + def pre_predict(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_predict(self, response): + logging.log(f"Received response: {response}") + return response + + transport = PredictionServiceRestTransport(interceptor=MyCustomPredictionServiceInterceptor()) + client = PredictionServiceClient(transport=transport) + + + """ + def pre_predict(self, request: prediction_service.PredictRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[prediction_service.PredictRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for predict + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_predict(self, response: prediction_service.PredictResponse) -> prediction_service.PredictResponse: + """Post-rpc interceptor for predict + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the PredictionService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the PredictionService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class PredictionServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: PredictionServiceRestInterceptor + + +class PredictionServiceRestTransport(PredictionServiceTransport): + """REST backend transport for PredictionService. + + Service for making recommendation prediction. + + 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 = 'retail.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[PredictionServiceRestInterceptor] = 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 PredictionServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _Predict(PredictionServiceRestStub): + def __hash__(self): + return hash("Predict") + + __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: prediction_service.PredictRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> prediction_service.PredictResponse: + r"""Call the predict method over HTTP. + + Args: + request (~.prediction_service.PredictRequest): + The request object. Request message for Predict 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: + ~.prediction_service.PredictResponse: + Response message for predict method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{placement=projects/*/locations/*/catalogs/*/placements/*}:predict', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v2beta/{placement=projects/*/locations/*/catalogs/*/servingConfigs/*}:predict', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_predict(request, metadata) + pb_request = prediction_service.PredictRequest.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 = prediction_service.PredictResponse() + pb_resp = prediction_service.PredictResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_predict(resp) + return resp + + @property + def predict(self) -> Callable[ + [prediction_service.PredictRequest], + prediction_service.PredictResponse]: + # 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._Predict(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(PredictionServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(PredictionServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'PredictionServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/__init__.py new file mode 100644 index 00000000..fee01226 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/__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 ProductServiceClient +from .async_client import ProductServiceAsyncClient + +__all__ = ( + 'ProductServiceClient', + 'ProductServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/async_client.py new file mode 100644 index 00000000..ed8ccade --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/async_client.py @@ -0,0 +1,1941 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.product_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product as gcr_product +from google.cloud.retail_v2beta.types import product_service +from google.cloud.retail_v2beta.types import promotion +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .client import ProductServiceClient + + +class ProductServiceAsyncClient: + """Service for ingesting [Product][google.cloud.retail.v2beta.Product] + information of the customer's website. + """ + + _client: ProductServiceClient + + DEFAULT_ENDPOINT = ProductServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ProductServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(ProductServiceClient.branch_path) + parse_branch_path = staticmethod(ProductServiceClient.parse_branch_path) + product_path = staticmethod(ProductServiceClient.product_path) + parse_product_path = staticmethod(ProductServiceClient.parse_product_path) + common_billing_account_path = staticmethod(ProductServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ProductServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ProductServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ProductServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ProductServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ProductServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ProductServiceClient.common_project_path) + parse_common_project_path = staticmethod(ProductServiceClient.parse_common_project_path) + common_location_path = staticmethod(ProductServiceClient.common_location_path) + parse_common_location_path = staticmethod(ProductServiceClient.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: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_info.__func__(ProductServiceAsyncClient, 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: + ProductServiceAsyncClient: The constructed client. + """ + return ProductServiceClient.from_service_account_file.__func__(ProductServiceAsyncClient, 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 ProductServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ProductServiceClient).get_transport_class, type(ProductServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ProductServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the product service 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, ~.ProductServiceTransport]): 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 = ProductServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_product(self, + request: Optional[Union[product_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + async def sample_create_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.CreateProductRequest, dict]]): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + method. + parent (:class:`str`): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (:class:`google.cloud.retail_v2beta.types.Product`): + Required. The + [Product][google.cloud.retail.v2beta.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`): + Required. The ID to use for the + [Product][google.cloud.retail.v2beta.Product], which + will become the final component of the + [Product.name][google.cloud.retail.v2beta.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This field must be unique among all + [Product][google.cloud.retail.v2beta.Product]s with the + same + [parent][google.cloud.retail.v2beta.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + 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.retail_v2beta.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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, + ) + + # Done; return the response. + return response + + async def get_product(self, + request: Optional[Union[product_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.Product: + r"""Gets a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + async def sample_get_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.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.retail_v2beta.types.GetProductRequest, dict]]): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + method. + name (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the requested + [Product][google.cloud.retail.v2beta.Product] does not + exist, a NOT_FOUND error is returned. + + 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.retail_v2beta.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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(( + ("name", request.name), + )), + ) + + # 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_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"""Gets a list of [Product][google.cloud.retail.v2beta.Product]s. + + .. 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 retail_v2beta + + async def sample_list_products(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.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.retail_v2beta.types.ListProductsRequest, dict]]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + method. + parent (:class:`str`): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2beta.Product]s under + this branch, regardless of whether or not this branch + exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2beta.services.product_service.pagers.ListProductsAsyncPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.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_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_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, + ) + + # 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 update_product(self, + request: Optional[Union[product_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + async def sample_update_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.UpdateProductRequest( + product=product, + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.UpdateProductRequest, dict]]): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + method. + product (:class:`google.cloud.retail_v2beta.types.Product`): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2beta.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + 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`): + Indicates which fields in the provided + [Product][google.cloud.retail.v2beta.Product] to update. + The immutable and output only fields are NOT supported. + If not set, all supported fields (the fields that are + neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask + path as "attributes.${key_name}". If a key name is + present in the mask but not in the patching product from + the request, this key will be deleted after the update. + + 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.retail_v2beta.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_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(( + ("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_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"""Deletes a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + async def sample_delete_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.DeleteProductRequest, dict]]): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2beta.ProductService.DeleteProduct] + method. + name (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2beta.Product] to + delete can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2beta.Product] member nor + a + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product] with more + than one + [variants][google.cloud.retail.v2beta.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2beta.Product] will be + deleted. + + 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_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_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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def import_products(self, + request: Optional[Union[import_config.ImportProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2beta.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2beta.Product]s to be + successfully updated. + + .. 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 retail_v2beta + + async def sample_import_products(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2beta.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2beta.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ImportProductsRequest, dict]]): + The request object. Request message for Import methods. + 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.retail_v2beta.types.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2beta.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportProductsRequest(request) + + # 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_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.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, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def set_inventory(self, + request: Optional[Union[product_service.SetInventoryRequest, dict]] = None, + *, + inventory: Optional[product.Product] = None, + set_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]] = (), + ) -> operation_async.AsyncOperation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2beta.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + .. 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 retail_v2beta + + async def sample_set_inventory(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + inventory = retail_v2beta.Product() + inventory.title = "title_value" + + request = retail_v2beta.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.SetInventoryRequest, dict]]): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + method. + inventory (:class:`google.cloud.retail_v2beta.types.Product`): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + - [Product.availability][google.cloud.retail.v2beta.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2beta.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2beta.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is + returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2beta.Product] named in + [Product.name][google.cloud.retail.v2beta.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2beta.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2beta.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + - [Product.availability][google.cloud.retail.v2beta.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2beta.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + should be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + set_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2beta.Product] to update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_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.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + method. + + """ + # 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([inventory, set_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_service.SetInventoryRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_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.set_inventory, + 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(( + ("inventory.name", request.inventory.name), + )), + ) + + # 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_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + async def add_fulfillment_places(self, + request: Optional[Union[product_service.AddFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + async def sample_add_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.AddFulfillmentPlacesRequest, dict]]): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2beta.types.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.AddFulfillmentPlacesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places, + 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(( + ("product", request.product), + )), + ) + + # 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_service.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def remove_fulfillment_places(self, + request: Optional[Union[product_service.RemoveFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + async def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.RemoveFulfillmentPlacesRequest, dict]]): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2beta.types.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.RemoveFulfillmentPlacesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places, + 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(( + ("product", request.product), + )), + ) + + # 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_service.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + async def add_local_inventories(self, + request: Optional[Union[product_service.AddLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Updates local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + async def sample_add_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.AddLocalInventoriesRequest, dict]]): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2beta.types.AddLocalInventoriesResponse` Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method. + + """ + # 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]) + 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_service.AddLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories, + 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(( + ("product", request.product), + )), + ) + + # 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_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + async def remove_local_inventories(self, + request: Optional[Union[product_service.RemoveLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Remove local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + async def sample_remove_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.RemoveLocalInventoriesRequest, dict]]): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method. + product (:class:`str`): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + 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.retail_v2beta.types.RemoveLocalInventoriesResponse` Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method. + + """ + # 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]) + 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_service.RemoveLocalInventoriesRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories, + 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(( + ("product", request.product), + )), + ) + + # 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_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ProductServiceAsyncClient": + 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__ = ( + "ProductServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/client.py new file mode 100644 index 00000000..15797b9d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/client.py @@ -0,0 +1,2151 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.product_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product as gcr_product +from google.cloud.retail_v2beta.types import product_service +from google.cloud.retail_v2beta.types import promotion +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from .transports.base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ProductServiceGrpcTransport +from .transports.grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .transports.rest import ProductServiceRestTransport + + +class ProductServiceClientMeta(type): + """Metaclass for the ProductService 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[ProductServiceTransport]] + _transport_registry["grpc"] = ProductServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ProductServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ProductServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ProductServiceTransport]: + """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 ProductServiceClient(metaclass=ProductServiceClientMeta): + """Service for ingesting [Product][google.cloud.retail.v2beta.Product] + information of the customer's website. + """ + + @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 = "retail.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: + ProductServiceClient: 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: + ProductServiceClient: 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) -> ProductServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ProductServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, ProductServiceTransport]] = 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 service 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, ProductServiceTransport]): 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, ProductServiceTransport): + # transport is a ProductServiceTransport 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(self, + request: Optional[Union[product_service.CreateProductRequest, dict]] = None, + *, + parent: Optional[str] = None, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Creates a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + def sample_create_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.CreateProductRequest, dict]): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + method. + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + product (google.cloud.retail_v2beta.types.Product): + Required. The + [Product][google.cloud.retail.v2beta.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): + Required. The ID to use for the + [Product][google.cloud.retail.v2beta.Product], which + will become the final component of the + [Product.name][google.cloud.retail.v2beta.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + This field must be unique among all + [Product][google.cloud.retail.v2beta.Product]s with the + same + [parent][google.cloud.retail.v2beta.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + 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.retail_v2beta.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.CreateProductRequest): + request = product_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 get_product(self, + request: Optional[Union[product_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.Product: + r"""Gets a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + def sample_get_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetProductRequest, dict]): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + method. + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the requested + [Product][google.cloud.retail.v2beta.Product] does not + exist, a NOT_FOUND error is returned. + + 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.retail_v2beta.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.GetProductRequest): + request = product_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 list_products(self, + request: Optional[Union[product_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"""Gets a list of [Product][google.cloud.retail.v2beta.Product]s. + + .. 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 retail_v2beta + + def sample_list_products(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.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.retail_v2beta.types.ListProductsRequest, dict]): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + method. + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list + products under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2beta.Product]s under + this branch, regardless of whether or not this branch + exists, a PERMISSION_DENIED error is returned. + + 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.retail_v2beta.services.product_service.pagers.ListProductsPager: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.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_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_service.ListProductsRequest): + request = product_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 update_product(self, + request: Optional[Union[product_service.UpdateProductRequest, dict]] = None, + *, + product: Optional[gcr_product.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]] = (), + ) -> gcr_product.Product: + r"""Updates a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + def sample_update_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.UpdateProductRequest( + product=product, + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateProductRequest, dict]): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + method. + product (google.cloud.retail_v2beta.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2beta.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + + 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): + Indicates which fields in the provided + [Product][google.cloud.retail.v2beta.Product] to update. + The immutable and output only fields are NOT supported. + If not set, all supported fields (the fields that are + neither immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask + path as "attributes.${key_name}". If a key name is + present in the mask but not in the patching product from + the request, this key will be deleted after the update. + + 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.retail_v2beta.types.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + # 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_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_service.UpdateProductRequest): + request = product_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_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"""Deletes a [Product][google.cloud.retail.v2beta.Product]. + + .. 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 retail_v2beta + + def sample_delete_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + Args: + request (Union[google.cloud.retail_v2beta.types.DeleteProductRequest, dict]): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2beta.ProductService.DeleteProduct] + method. + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2beta.Product] to + delete can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2beta.Product] member nor + a + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product] with more + than one + [variants][google.cloud.retail.v2beta.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2beta.Product] will be + deleted. + + 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_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_service.DeleteProductRequest): + request = product_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 import_products(self, + request: Optional[Union[import_config.ImportProductsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of multiple + [Product][google.cloud.retail.v2beta.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2beta.Product]s to be + successfully updated. + + .. 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 retail_v2beta + + def sample_import_products(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + input_config = retail_v2beta.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2beta.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ImportProductsRequest, dict]): + The request object. Request message for Import methods. + 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.retail_v2beta.types.ImportProductsResponse` Response of the + [ImportProductsRequest][google.cloud.retail.v2beta.ImportProductsRequest]. + If the long running operation is done, then this + message is returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportProductsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportProductsRequest): + request = import_config.ImportProductsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_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, + import_config.ImportProductsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def set_inventory(self, + request: Optional[Union[product_service.SetInventoryRequest, dict]] = None, + *, + inventory: Optional[product.Product] = None, + set_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]] = (), + ) -> operation.Operation: + r"""Updates inventory information for a + [Product][google.cloud.retail.v2beta.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + .. 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 retail_v2beta + + def sample_set_inventory(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + inventory = retail_v2beta.Product() + inventory.title = "title_value" + + request = retail_v2beta.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.SetInventoryRequest, dict]): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + method. + inventory (google.cloud.retail_v2beta.types.Product): + Required. The inventory information to update. The + allowable fields to update are: + + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + - [Product.availability][google.cloud.retail.v2beta.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2beta.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2beta.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is + returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2beta.Product] named in + [Product.name][google.cloud.retail.v2beta.Product.name], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2beta.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting + the last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2beta.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear + in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + - Checks that only the desired fulfillment info types + have empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + + The last update time is recorded for the following + inventory fields: + + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + - [Product.availability][google.cloud.retail.v2beta.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2beta.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + + If a full overwrite of inventory information while + ignoring timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + should be invoked instead. + + This corresponds to the ``inventory`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + set_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2beta.Product] to update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + + This corresponds to the ``set_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.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.SetInventoryResponse` Response of the SetInventoryRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + method. + + """ + # 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([inventory, set_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_service.SetInventoryRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.SetInventoryRequest): + request = product_service.SetInventoryRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if inventory is not None: + request.inventory = inventory + if set_mask is not None: + request.set_mask = set_mask + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.set_inventory] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("inventory.name", request.inventory.name), + )), + ) + + # 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_service.SetInventoryResponse, + metadata_type=product_service.SetInventoryMetadata, + ) + + # Done; return the response. + return response + + def add_fulfillment_places(self, + request: Optional[Union[product_service.AddFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + def sample_add_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.AddFulfillmentPlacesRequest, dict]): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.AddFulfillmentPlacesResponse` Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.AddFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddFulfillmentPlacesRequest): + request = product_service.AddFulfillmentPlacesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.AddFulfillmentPlacesResponse, + metadata_type=product_service.AddFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def remove_fulfillment_places(self, + request: Optional[Union[product_service.RemoveFulfillmentPlacesRequest, dict]] = None, + *, + product: 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"""It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.RemoveFulfillmentPlacesRequest, dict]): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.RemoveFulfillmentPlacesResponse` Response of the RemoveFulfillmentPlacesRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + method. + + """ + # 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]) + 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_service.RemoveFulfillmentPlacesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveFulfillmentPlacesRequest): + request = product_service.RemoveFulfillmentPlacesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_fulfillment_places] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.RemoveFulfillmentPlacesResponse, + metadata_type=product_service.RemoveFulfillmentPlacesMetadata, + ) + + # Done; return the response. + return response + + def add_local_inventories(self, + request: Optional[Union[product_service.AddLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Updates local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + def sample_add_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.AddLocalInventoriesRequest, dict]): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.AddLocalInventoriesResponse` Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method. + + """ + # 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]) + 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_service.AddLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.AddLocalInventoriesRequest): + request = product_service.AddLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.AddLocalInventoriesResponse, + metadata_type=product_service.AddLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + def remove_local_inventories(self, + request: Optional[Union[product_service.RemoveLocalInventoriesRequest, dict]] = None, + *, + product: 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"""Remove local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + .. 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 retail_v2beta + + def sample_remove_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.RemoveLocalInventoriesRequest, dict]): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method. + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], + regardless of whether or not it exists, a + PERMISSION_DENIED error is returned. + + 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. + + Returns: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.RemoveLocalInventoriesResponse` Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful + response populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method. + + """ + # 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]) + 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_service.RemoveLocalInventoriesRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, product_service.RemoveLocalInventoriesRequest): + request = product_service.RemoveLocalInventoriesRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + 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_local_inventories] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("product", request.product), + )), + ) + + # 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_service.RemoveLocalInventoriesResponse, + metadata_type=product_service.RemoveLocalInventoriesMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ProductServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ProductServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/pagers.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/pagers.py new file mode 100644 index 00000000..0b7af86f --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product_service + + +class ListProductsPager: + """A pager for iterating through ``list_products`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.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.retail_v2beta.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_service.ListProductsResponse], + request: product_service.ListProductsRequest, + response: product_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.retail_v2beta.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2beta.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_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_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.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.retail_v2beta.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.retail_v2beta.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_service.ListProductsResponse]], + request: product_service.ListProductsRequest, + response: product_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.retail_v2beta.types.ListProductsRequest): + The initial request object. + response (google.cloud.retail_v2beta.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_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_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.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/v2beta/google/cloud/retail_v2beta/services/product_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/__init__.py new file mode 100644 index 00000000..b9528228 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/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 ProductServiceTransport +from .grpc import ProductServiceGrpcTransport +from .grpc_asyncio import ProductServiceGrpcAsyncIOTransport +from .rest import ProductServiceRestTransport +from .rest import ProductServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ProductServiceTransport]] +_transport_registry['grpc'] = ProductServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ProductServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ProductServiceRestTransport + +__all__ = ( + 'ProductServiceTransport', + 'ProductServiceGrpcTransport', + 'ProductServiceGrpcAsyncIOTransport', + 'ProductServiceRestTransport', + 'ProductServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/base.py new file mode 100644 index 00000000..0e4cd0ca --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/base.py @@ -0,0 +1,325 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product as gcr_product +from google.cloud.retail_v2beta.types import product_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 ProductServiceTransport(abc.ABC): + """Abstract transport class for ProductService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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: gapic_v1.method.wrap_method( + self.create_product, + default_timeout=None, + client_info=client_info, + ), + self.get_product: gapic_v1.method.wrap_method( + self.get_product, + default_timeout=None, + client_info=client_info, + ), + self.list_products: gapic_v1.method.wrap_method( + self.list_products, + default_timeout=None, + client_info=client_info, + ), + self.update_product: gapic_v1.method.wrap_method( + self.update_product, + default_timeout=None, + client_info=client_info, + ), + self.delete_product: gapic_v1.method.wrap_method( + self.delete_product, + default_timeout=None, + client_info=client_info, + ), + self.import_products: gapic_v1.method.wrap_method( + self.import_products, + default_retry=retries.Retry( +initial=0.1,maximum=300.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=300.0, + ), + default_timeout=300.0, + client_info=client_info, + ), + self.set_inventory: gapic_v1.method.wrap_method( + self.set_inventory, + default_timeout=None, + client_info=client_info, + ), + self.add_fulfillment_places: gapic_v1.method.wrap_method( + self.add_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + self.remove_fulfillment_places: gapic_v1.method.wrap_method( + self.remove_fulfillment_places, + default_timeout=None, + client_info=client_info, + ), + self.add_local_inventories: gapic_v1.method.wrap_method( + self.add_local_inventories, + default_timeout=None, + client_info=client_info, + ), + self.remove_local_inventories: gapic_v1.method.wrap_method( + self.remove_local_inventories, + 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(self) -> Callable[ + [product_service.CreateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Union[ + product.Product, + Awaitable[product.Product] + ]]: + raise NotImplementedError() + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Union[ + product_service.ListProductsResponse, + Awaitable[product_service.ListProductsResponse] + ]]: + raise NotImplementedError() + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Union[ + gcr_product.Product, + Awaitable[gcr_product.Product] + ]]: + raise NotImplementedError() + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ProductServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc.py new file mode 100644 index 00000000..a1e93408 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc.py @@ -0,0 +1,764 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product as gcr_product +from google.cloud.retail_v2beta.types import product_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO + + +class ProductServiceGrpcTransport(ProductServiceTransport): + """gRPC backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2beta.Product] + information of the customer's website. + + 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 = 'retail.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 = 'retail.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(self) -> Callable[ + [product_service.CreateProductRequest], + gcr_product.Product]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + product.Product]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + product_service.ListProductsResponse]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2beta.Product]s. + + 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.retail.v2beta.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + gcr_product.Product]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2beta.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2beta.Product]s to be + successfully updated. + + Returns: + Callable[[~.ImportProductsRequest], + ~.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_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + operations_pb2.Operation]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2beta.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + Returns: + Callable[[~.SetInventoryRequest], + ~.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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the add fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddFulfillmentPlacesRequest], + ~.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 'add_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + operations_pb2.Operation]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveFulfillmentPlacesRequest], + ~.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 'remove_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + operations_pb2.Operation]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + ~.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 'add_local_inventories' not in self._stubs: + self._stubs['add_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/AddLocalInventories', + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_local_inventories'] + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + operations_pb2.Operation]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + ~.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 'remove_local_inventories' not in self._stubs: + self._stubs['remove_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/RemoveLocalInventories', + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_local_inventories'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ProductServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..4cfbb12f --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/grpc_asyncio.py @@ -0,0 +1,763 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product as gcr_product +from google.cloud.retail_v2beta.types import product_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ProductServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ProductServiceGrpcTransport + + +class ProductServiceGrpcAsyncIOTransport(ProductServiceTransport): + """gRPC AsyncIO backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2beta.Product] + information of the customer's website. + + 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 = 'retail.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 = 'retail.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(self) -> Callable[ + [product_service.CreateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the create product method over gRPC. + + Creates a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/CreateProduct', + request_serializer=product_service.CreateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['create_product'] + + @property + def get_product(self) -> Callable[ + [product_service.GetProductRequest], + Awaitable[product.Product]]: + r"""Return a callable for the get product method over gRPC. + + Gets a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/GetProduct', + request_serializer=product_service.GetProductRequest.serialize, + response_deserializer=product.Product.deserialize, + ) + return self._stubs['get_product'] + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + Awaitable[product_service.ListProductsResponse]]: + r"""Return a callable for the list products method over gRPC. + + Gets a list of [Product][google.cloud.retail.v2beta.Product]s. + + 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.retail.v2beta.ProductService/ListProducts', + request_serializer=product_service.ListProductsRequest.serialize, + response_deserializer=product_service.ListProductsResponse.deserialize, + ) + return self._stubs['list_products'] + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + Awaitable[gcr_product.Product]]: + r"""Return a callable for the update product method over gRPC. + + Updates a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/UpdateProduct', + request_serializer=product_service.UpdateProductRequest.serialize, + response_deserializer=gcr_product.Product.deserialize, + ) + return self._stubs['update_product'] + + @property + def delete_product(self) -> Callable[ + [product_service.DeleteProductRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete product method over gRPC. + + Deletes a [Product][google.cloud.retail.v2beta.Product]. + + 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.retail.v2beta.ProductService/DeleteProduct', + request_serializer=product_service.DeleteProductRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_product'] + + @property + def import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import products method over gRPC. + + Bulk import of multiple + [Product][google.cloud.retail.v2beta.Product]s. + + Request processing may be synchronous. Non-existing items are + created. + + Note that it is possible for a subset of the + [Product][google.cloud.retail.v2beta.Product]s to be + successfully updated. + + Returns: + Callable[[~.ImportProductsRequest], + 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_products' not in self._stubs: + self._stubs['import_products'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/ImportProducts', + request_serializer=import_config.ImportProductsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_products'] + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the set inventory method over gRPC. + + Updates inventory information for a + [Product][google.cloud.retail.v2beta.Product] while respecting + the last update timestamps of each inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update is enqueued and processed downstream. As a consequence, + when a response is returned, updates are not immediately + manifested in the [Product][google.cloud.retail.v2beta.Product] + queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + When inventory is updated with + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct], + the specified inventory field value(s) overwrite any existing + value(s) while ignoring the last update time for this field. + Furthermore, the last update times for the specified inventory + fields are overwritten by the times of the + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + or + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + request. + + If no inventory fields are set in + [CreateProductRequest.product][google.cloud.retail.v2beta.CreateProductRequest.product], + then any pre-existing inventory information for this product is + used. + + If no inventory fields are set in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask], + then any existing inventory information is preserved. + + Pre-existing inventory information can only be updated with + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory], + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces], + and + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + + The returned [Operation][google.longrunning.Operation]s is + obsolete after one day, and the + [GetOperation][google.longrunning.Operations.GetOperation] API + returns ``NOT_FOUND`` afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates are not marked as + [done][google.longrunning.Operation.done] until they are + obsolete. + + Returns: + Callable[[~.SetInventoryRequest], + 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 'set_inventory' not in self._stubs: + self._stubs['set_inventory'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/SetInventory', + request_serializer=product_service.SetInventoryRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['set_inventory'] + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the add fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method instead of + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces]. + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally adds place IDs to + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the added place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddFulfillmentPlacesRequest], + 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 'add_fulfillment_places' not in self._stubs: + self._stubs['add_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/AddFulfillmentPlaces', + request_serializer=product_service.AddFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_fulfillment_places'] + + @property + def remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the remove fulfillment places method over gRPC. + + It is recommended to use the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method instead of + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces]. + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + achieves the same results but provides more fine-grained control + over ingesting local inventory data. + + Incrementally removes place IDs from a + [Product.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids]. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating fulfillment information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, the removed place IDs + are not immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveFulfillmentPlacesRequest], + 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 'remove_fulfillment_places' not in self._stubs: + self._stubs['remove_fulfillment_places'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/RemoveFulfillmentPlaces', + request_serializer=product_service.RemoveFulfillmentPlacesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_fulfillment_places'] + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the add local inventories method over gRPC. + + Updates local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places, while respecting the last update timestamps of each + inventory field. + + This process is asynchronous and does not require the + [Product][google.cloud.retail.v2beta.Product] to exist before + updating inventory information. If the request is valid, the + update will be enqueued and processed downstream. As a + consequence, when a response is returned, updates are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be modified using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.AddLocalInventoriesRequest], + 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 'add_local_inventories' not in self._stubs: + self._stubs['add_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/AddLocalInventories', + request_serializer=product_service.AddLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['add_local_inventories'] + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the remove local inventories method over gRPC. + + Remove local inventory information for a + [Product][google.cloud.retail.v2beta.Product] at a list of + places at a removal timestamp. + + This process is asynchronous. If the request is valid, the + removal will be enqueued and processed downstream. As a + consequence, when a response is returned, removals are not + immediately manifested in the + [Product][google.cloud.retail.v2beta.Product] queried by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + or + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + Local inventory information can only be removed using this + method. + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + and + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + has no effect on local inventories. + + The returned [Operation][google.longrunning.Operation]s will be + obsolete after 1 day, and + [GetOperation][google.longrunning.Operations.GetOperation] API + will return NOT_FOUND afterwards. + + If conflicting updates are issued, the + [Operation][google.longrunning.Operation]s associated with the + stale updates will not be marked as + [done][google.longrunning.Operation.done] until being obsolete. + + Returns: + Callable[[~.RemoveLocalInventoriesRequest], + 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 'remove_local_inventories' not in self._stubs: + self._stubs['remove_local_inventories'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ProductService/RemoveLocalInventories', + request_serializer=product_service.RemoveLocalInventoriesRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['remove_local_inventories'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ProductServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/rest.py new file mode 100644 index 00000000..3c81d721 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/product_service/transports/rest.py @@ -0,0 +1,1731 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product as gcr_product +from google.cloud.retail_v2beta.types import product_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ProductServiceTransport, 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 ProductServiceRestInterceptor: + """Interceptor for ProductService. + + 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 ProductServiceRestTransport. + + .. code-block:: python + class MyCustomProductServiceInterceptor(ProductServiceRestInterceptor): + def pre_add_fulfillment_places(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_fulfillment_places(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_add_local_inventories(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_local_inventories(self, response): + logging.log(f"Received response: {response}") + return response + + 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_delete_product(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_import_products(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_products(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_remove_fulfillment_places(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_fulfillment_places(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_local_inventories(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_local_inventories(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_set_inventory(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_set_inventory(self, response): + logging.log(f"Received response: {response}") + return response + + 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 + + transport = ProductServiceRestTransport(interceptor=MyCustomProductServiceInterceptor()) + client = ProductServiceClient(transport=transport) + + + """ + def pre_add_fulfillment_places(self, request: product_service.AddFulfillmentPlacesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.AddFulfillmentPlacesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_fulfillment_places + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_add_fulfillment_places(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for add_fulfillment_places + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_add_local_inventories(self, request: product_service.AddLocalInventoriesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.AddLocalInventoriesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_local_inventories + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_add_local_inventories(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for add_local_inventories + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_create_product(self, request: product_service.CreateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_create_product(self, response: gcr_product.Product) -> gcr_product.Product: + """Post-rpc interceptor for create_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_delete_product(self, request: product_service.DeleteProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def pre_get_product(self, request: product_service.GetProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_get_product(self, response: product.Product) -> product.Product: + """Post-rpc interceptor for get_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_import_products(self, request: import_config.ImportProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportProductsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_products + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_import_products(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_products + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_list_products(self, request: product_service.ListProductsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_list_products(self, response: product_service.ListProductsResponse) -> product_service.ListProductsResponse: + """Post-rpc interceptor for list_products + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_remove_fulfillment_places(self, request: product_service.RemoveFulfillmentPlacesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.RemoveFulfillmentPlacesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_fulfillment_places + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_remove_fulfillment_places(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for remove_fulfillment_places + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_remove_local_inventories(self, request: product_service.RemoveLocalInventoriesRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.RemoveLocalInventoriesRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_local_inventories + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_remove_local_inventories(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for remove_local_inventories + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_set_inventory(self, request: product_service.SetInventoryRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_service.SetInventoryRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for set_inventory + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_set_inventory(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for set_inventory + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_update_product(self, request: product_service.UpdateProductRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[product_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 ProductService server. + """ + return request, metadata + + def post_update_product(self, response: gcr_product.Product) -> gcr_product.Product: + """Post-rpc interceptor for update_product + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ProductService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ProductService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ProductServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ProductServiceRestInterceptor + + +class ProductServiceRestTransport(ProductServiceTransport): + """REST backend transport for ProductService. + + Service for ingesting [Product][google.cloud.retail.v2beta.Product] + information of the customer's website. + + 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 = 'retail.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[ProductServiceRestInterceptor] = 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 ProductServiceRestInterceptor() + 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/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="v2beta") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _AddFulfillmentPlaces(ProductServiceRestStub): + def __hash__(self): + return hash("AddFulfillmentPlaces") + + __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_service.AddFulfillmentPlacesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the add fulfillment places method over HTTP. + + Args: + request (~.product_service.AddFulfillmentPlacesRequest): + The request object. Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + 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': '/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addFulfillmentPlaces', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_fulfillment_places(request, metadata) + pb_request = product_service.AddFulfillmentPlacesRequest.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_add_fulfillment_places(resp) + return resp + + class _AddLocalInventories(ProductServiceRestStub): + def __hash__(self): + return hash("AddLocalInventories") + + __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_service.AddLocalInventoriesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the add local inventories method over HTTP. + + Args: + request (~.product_service.AddLocalInventoriesRequest): + The request object. Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + 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': '/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addLocalInventories', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_local_inventories(request, metadata) + pb_request = product_service.AddLocalInventoriesRequest.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_add_local_inventories(resp) + return resp + + class _CreateProduct(ProductServiceRestStub): + def __hash__(self): + return hash("CreateProduct") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "productId" : "", } + + @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_service.CreateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_product.Product: + r"""Call the create product method over HTTP. + + Args: + request (~.product_service.CreateProductRequest): + The request object. Request message for + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.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: + ~.gcr_product.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*/branches/*}/products', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_create_product(request, metadata) + pb_request = product_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 = gcr_product.Product() + pb_resp = gcr_product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_product(resp) + return resp + + class _DeleteProduct(ProductServiceRestStub): + 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_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_service.DeleteProductRequest): + The request object. Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2beta.ProductService.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': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + }, + ] + request, metadata = self._interceptor.pre_delete_product(request, metadata) + pb_request = product_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 _GetProduct(ProductServiceRestStub): + 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_service.GetProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product.Product: + r"""Call the get product method over HTTP. + + Args: + request (~.product_service.GetProductRequest): + The request object. Request message for + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.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.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + }, + ] + request, metadata = self._interceptor.pre_get_product(request, metadata) + pb_request = product_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.Product() + pb_resp = product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_product(resp) + return resp + + class _ImportProducts(ProductServiceRestStub): + def __hash__(self): + return hash("ImportProducts") + + __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: import_config.ImportProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import products method over HTTP. + + Args: + request (~.import_config.ImportProductsRequest): + The request object. Request message for Import methods. + 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': '/v2beta/{parent=projects/*/locations/*/catalogs/*/branches/*}/products:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_products(request, metadata) + pb_request = import_config.ImportProductsRequest.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_products(resp) + return resp + + class _ListProducts(ProductServiceRestStub): + 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_service.ListProductsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> product_service.ListProductsResponse: + r"""Call the list products method over HTTP. + + Args: + request (~.product_service.ListProductsRequest): + The request object. Request message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.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_service.ListProductsResponse: + Response message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*/branches/*}/products', + }, + ] + request, metadata = self._interceptor.pre_list_products(request, metadata) + pb_request = product_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_service.ListProductsResponse() + pb_resp = product_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 _RemoveFulfillmentPlaces(ProductServiceRestStub): + def __hash__(self): + return hash("RemoveFulfillmentPlaces") + + __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_service.RemoveFulfillmentPlacesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the remove fulfillment places method over HTTP. + + Args: + request (~.product_service.RemoveFulfillmentPlacesRequest): + The request object. Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + 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': '/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeFulfillmentPlaces', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_fulfillment_places(request, metadata) + pb_request = product_service.RemoveFulfillmentPlacesRequest.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_remove_fulfillment_places(resp) + return resp + + class _RemoveLocalInventories(ProductServiceRestStub): + def __hash__(self): + return hash("RemoveLocalInventories") + + __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_service.RemoveLocalInventoriesRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the remove local inventories method over HTTP. + + Args: + request (~.product_service.RemoveLocalInventoriesRequest): + The request object. Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + 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': '/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeLocalInventories', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_local_inventories(request, metadata) + pb_request = product_service.RemoveLocalInventoriesRequest.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_remove_local_inventories(resp) + return resp + + class _SetInventory(ProductServiceRestStub): + def __hash__(self): + return hash("SetInventory") + + __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_service.SetInventoryRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the set inventory method over HTTP. + + Args: + request (~.product_service.SetInventoryRequest): + The request object. Request message for + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + 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': '/v2beta/{inventory.name=projects/*/locations/*/catalogs/*/branches/*/products/**}:setInventory', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_set_inventory(request, metadata) + pb_request = product_service.SetInventoryRequest.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_set_inventory(resp) + return resp + + class _UpdateProduct(ProductServiceRestStub): + 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_service.UpdateProductRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_product.Product: + r"""Call the update product method over HTTP. + + Args: + request (~.product_service.UpdateProductRequest): + The request object. Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.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: + ~.gcr_product.Product: + Product captures all metadata + information of items to be recommended + or searched. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2beta/{product.name=projects/*/locations/*/catalogs/*/branches/*/products/**}', + 'body': 'product', + }, + ] + request, metadata = self._interceptor.pre_update_product(request, metadata) + pb_request = product_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 = gcr_product.Product() + pb_resp = gcr_product.Product.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_product(resp) + return resp + + @property + def add_fulfillment_places(self) -> Callable[ + [product_service.AddFulfillmentPlacesRequest], + 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._AddFulfillmentPlaces(self._session, self._host, self._interceptor) # type: ignore + + @property + def add_local_inventories(self) -> Callable[ + [product_service.AddLocalInventoriesRequest], + 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._AddLocalInventories(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_product(self) -> Callable[ + [product_service.CreateProductRequest], + gcr_product.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 delete_product(self) -> Callable[ + [product_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 get_product(self) -> Callable[ + [product_service.GetProductRequest], + product.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 import_products(self) -> Callable[ + [import_config.ImportProductsRequest], + 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._ImportProducts(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_products(self) -> Callable[ + [product_service.ListProductsRequest], + product_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 remove_fulfillment_places(self) -> Callable[ + [product_service.RemoveFulfillmentPlacesRequest], + 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._RemoveFulfillmentPlaces(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_local_inventories(self) -> Callable[ + [product_service.RemoveLocalInventoriesRequest], + 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._RemoveLocalInventories(self._session, self._host, self._interceptor) # type: ignore + + @property + def set_inventory(self) -> Callable[ + [product_service.SetInventoryRequest], + 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._SetInventory(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_product(self) -> Callable[ + [product_service.UpdateProductRequest], + gcr_product.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 get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ProductServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ProductServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ProductServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/__init__.py new file mode 100644 index 00000000..0355170e --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/__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 SearchServiceClient +from .async_client import SearchServiceAsyncClient + +__all__ = ( + 'SearchServiceClient', + 'SearchServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/async_client.py new file mode 100644 index 00000000..e80ff5f9 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/async_client.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 collections import OrderedDict +import functools +import re +from typing import Dict, Mapping, MutableMapping, MutableSequence, Optional, Sequence, Tuple, Type, Union + +from google.cloud.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.search_service import pagers +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .client import SearchServiceClient + + +class SearchServiceAsyncClient: + """Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + _client: SearchServiceClient + + DEFAULT_ENDPOINT = SearchServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = SearchServiceClient.DEFAULT_MTLS_ENDPOINT + + branch_path = staticmethod(SearchServiceClient.branch_path) + parse_branch_path = staticmethod(SearchServiceClient.parse_branch_path) + experiment_path = staticmethod(SearchServiceClient.experiment_path) + parse_experiment_path = staticmethod(SearchServiceClient.parse_experiment_path) + product_path = staticmethod(SearchServiceClient.product_path) + parse_product_path = staticmethod(SearchServiceClient.parse_product_path) + serving_config_path = staticmethod(SearchServiceClient.serving_config_path) + parse_serving_config_path = staticmethod(SearchServiceClient.parse_serving_config_path) + common_billing_account_path = staticmethod(SearchServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(SearchServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(SearchServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(SearchServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(SearchServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(SearchServiceClient.parse_common_organization_path) + common_project_path = staticmethod(SearchServiceClient.common_project_path) + parse_common_project_path = staticmethod(SearchServiceClient.parse_common_project_path) + common_location_path = staticmethod(SearchServiceClient.common_location_path) + parse_common_location_path = staticmethod(SearchServiceClient.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: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_info.__func__(SearchServiceAsyncClient, 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: + SearchServiceAsyncClient: The constructed client. + """ + return SearchServiceClient.from_service_account_file.__func__(SearchServiceAsyncClient, 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 SearchServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(SearchServiceClient).get_transport_class, type(SearchServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, SearchServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service 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, ~.SearchServiceTransport]): 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 = SearchServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def search(self, + request: Optional[Union[search_service.SearchRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchAsyncPager: + r"""Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2beta + + async def sample_search(): + # Create a client + client = retail_v2beta.SearchServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.SearchRequest, dict]]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + 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: + google.cloud.retail_v2beta.services.search_service.pagers.SearchAsyncPager: + Response message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.search, + 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(( + ("placement", request.placement), + )), + ) + + # 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.SearchAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "SearchServiceAsyncClient": + 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__ = ( + "SearchServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/client.py new file mode 100644 index 00000000..d346d2ce --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/client.py @@ -0,0 +1,649 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.search_service import pagers +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .transports.base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import SearchServiceGrpcTransport +from .transports.grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .transports.rest import SearchServiceRestTransport + + +class SearchServiceClientMeta(type): + """Metaclass for the SearchService 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[SearchServiceTransport]] + _transport_registry["grpc"] = SearchServiceGrpcTransport + _transport_registry["grpc_asyncio"] = SearchServiceGrpcAsyncIOTransport + _transport_registry["rest"] = SearchServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[SearchServiceTransport]: + """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 SearchServiceClient(metaclass=SearchServiceClientMeta): + """Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + """ + + @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 = "retail.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: + SearchServiceClient: 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: + SearchServiceClient: 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) -> SearchServiceTransport: + """Returns the transport used by the client instance. + + Returns: + SearchServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def branch_path(project: str,location: str,catalog: str,branch: str,) -> str: + """Returns a fully-qualified branch string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + + @staticmethod + def parse_branch_path(path: str) -> Dict[str,str]: + """Parses a branch path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/branches/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def experiment_path(project: str,location: str,catalog: str,experiment: str,) -> str: + """Returns a fully-qualified experiment string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format(project=project, location=location, catalog=catalog, experiment=experiment, ) + + @staticmethod + def parse_experiment_path(path: str) -> Dict[str,str]: + """Parses a experiment path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/experiments/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def serving_config_path(project: str,location: str,catalog: str,serving_config: str,) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str,str]: + """Parses a serving_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?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, SearchServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the search service 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, SearchServiceTransport]): 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, SearchServiceTransport): + # transport is a SearchServiceTransport 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 search(self, + request: Optional[Union[search_service.SearchRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> pagers.SearchPager: + r"""Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + .. 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 retail_v2beta + + def sample_search(): + # Create a client + client = retail_v2beta.SearchServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.SearchRequest, dict]): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + 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: + google.cloud.retail_v2beta.services.search_service.pagers.SearchPager: + Response message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + method. + + Iterating over this object will yield results and + resolve additional pages automatically. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a search_service.SearchRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, search_service.SearchRequest): + request = search_service.SearchRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.search] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("placement", request.placement), + )), + ) + + # 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.SearchPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "SearchServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "SearchServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/pagers.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/pagers.py new file mode 100644 index 00000000..a50f64be --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/pagers.py @@ -0,0 +1,139 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import search_service + + +class SearchPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.SearchResponse` object, and + provides an ``__iter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.SearchResponse` + 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[..., search_service.SearchResponse], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + 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.retail_v2beta.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.SearchResponse): + 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 = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[search_service.SearchResponse]: + 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[search_service.SearchResponse.SearchResult]: + for page in self.pages: + yield from page.results + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class SearchAsyncPager: + """A pager for iterating through ``search`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.SearchResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``results`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``Search`` requests and continue to iterate + through the ``results`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.SearchResponse` + 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[search_service.SearchResponse]], + request: search_service.SearchRequest, + response: search_service.SearchResponse, + *, + 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.retail_v2beta.types.SearchRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.SearchResponse): + 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 = search_service.SearchRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[search_service.SearchResponse]: + 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[search_service.SearchResponse.SearchResult]: + async def async_generator(): + async for page in self.pages: + for response in page.results: + 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/v2beta/google/cloud/retail_v2beta/services/search_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/__init__.py new file mode 100644 index 00000000..4282aef0 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/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 SearchServiceTransport +from .grpc import SearchServiceGrpcTransport +from .grpc_asyncio import SearchServiceGrpcAsyncIOTransport +from .rest import SearchServiceRestTransport +from .rest import SearchServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[SearchServiceTransport]] +_transport_registry['grpc'] = SearchServiceGrpcTransport +_transport_registry['grpc_asyncio'] = SearchServiceGrpcAsyncIOTransport +_transport_registry['rest'] = SearchServiceRestTransport + +__all__ = ( + 'SearchServiceTransport', + 'SearchServiceGrpcTransport', + 'SearchServiceGrpcAsyncIOTransport', + 'SearchServiceRestTransport', + 'SearchServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/base.py new file mode 100644 index 00000000..39aeae9e --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/base.py @@ -0,0 +1,168 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class SearchServiceTransport(abc.ABC): + """Abstract transport class for SearchService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.search: gapic_v1.method.wrap_method( + self.search, + 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 search(self) -> Callable[ + [search_service.SearchRequest], + Union[ + search_service.SearchResponse, + Awaitable[search_service.SearchResponse] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'SearchServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc.py new file mode 100644 index 00000000..10595f92 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc.py @@ -0,0 +1,310 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO + + +class SearchServiceGrpcTransport(SearchServiceTransport): + """gRPC backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 search(self) -> Callable[ + [search_service.SearchRequest], + search_service.SearchResponse]: + r"""Return a callable for the search method over gRPC. + + Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.SearchRequest], + ~.SearchResponse]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'SearchServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..e90ad7ab --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/grpc_asyncio.py @@ -0,0 +1,309 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from .base import SearchServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import SearchServiceGrpcTransport + + +class SearchServiceGrpcAsyncIOTransport(SearchServiceTransport): + """gRPC AsyncIO backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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 = 'retail.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 search(self) -> Callable[ + [search_service.SearchRequest], + Awaitable[search_service.SearchResponse]]: + r"""Return a callable for the search method over gRPC. + + Performs a search. + + This feature is only available for users who have Retail + Search enabled. Enable Retail Search on Cloud Console + before using this feature. + + Returns: + Callable[[~.SearchRequest], + Awaitable[~.SearchResponse]]: + 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 'search' not in self._stubs: + self._stubs['search'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.SearchService/Search', + request_serializer=search_service.SearchRequest.serialize, + response_deserializer=search_service.SearchResponse.deserialize, + ) + return self._stubs['search'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'SearchServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/rest.py new file mode 100644 index 00000000..abaa2b6c --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/search_service/transports/rest.py @@ -0,0 +1,504 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import SearchServiceTransport, 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 SearchServiceRestInterceptor: + """Interceptor for SearchService. + + 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 SearchServiceRestTransport. + + .. code-block:: python + class MyCustomSearchServiceInterceptor(SearchServiceRestInterceptor): + def pre_search(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_search(self, response): + logging.log(f"Received response: {response}") + return response + + transport = SearchServiceRestTransport(interceptor=MyCustomSearchServiceInterceptor()) + client = SearchServiceClient(transport=transport) + + + """ + def pre_search(self, request: search_service.SearchRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[search_service.SearchRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for search + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_search(self, response: search_service.SearchResponse) -> search_service.SearchResponse: + """Post-rpc interceptor for search + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the SearchService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the SearchService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class SearchServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: SearchServiceRestInterceptor + + +class SearchServiceRestTransport(SearchServiceTransport): + """REST backend transport for SearchService. + + Service for search. + + This feature is only available for users who have Retail Search + enabled. Enable Retail Search on Cloud Console before using this + feature. + + 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 = 'retail.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[SearchServiceRestInterceptor] = 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 SearchServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _Search(SearchServiceRestStub): + def __hash__(self): + return hash("Search") + + __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: search_service.SearchRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> search_service.SearchResponse: + r"""Call the search method over HTTP. + + Args: + request (~.search_service.SearchRequest): + The request object. Request message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + 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: + ~.search_service.SearchResponse: + Response message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{placement=projects/*/locations/*/catalogs/*/placements/*}:search', + 'body': '*', + }, +{ + 'method': 'post', + 'uri': '/v2beta/{placement=projects/*/locations/*/catalogs/*/servingConfigs/*}:search', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_search(request, metadata) + pb_request = search_service.SearchRequest.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 = search_service.SearchResponse() + pb_resp = search_service.SearchResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_search(resp) + return resp + + @property + def search(self) -> Callable[ + [search_service.SearchRequest], + search_service.SearchResponse]: + # 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._Search(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(SearchServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(SearchServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'SearchServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/__init__.py new file mode 100644 index 00000000..3d167dee --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/__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 ServingConfigServiceClient +from .async_client import ServingConfigServiceAsyncClient + +__all__ = ( + 'ServingConfigServiceClient', + 'ServingConfigServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/async_client.py new file mode 100644 index 00000000..5e9b475f --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/async_client.py @@ -0,0 +1,1098 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.serving_config_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import search_service +from google.cloud.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config as gcr_serving_config +from google.cloud.retail_v2beta.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .client import ServingConfigServiceClient + + +class ServingConfigServiceAsyncClient: + """Service for modifying ServingConfig.""" + + _client: ServingConfigServiceClient + + DEFAULT_ENDPOINT = ServingConfigServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = ServingConfigServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(ServingConfigServiceClient.catalog_path) + parse_catalog_path = staticmethod(ServingConfigServiceClient.parse_catalog_path) + serving_config_path = staticmethod(ServingConfigServiceClient.serving_config_path) + parse_serving_config_path = staticmethod(ServingConfigServiceClient.parse_serving_config_path) + common_billing_account_path = staticmethod(ServingConfigServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(ServingConfigServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(ServingConfigServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(ServingConfigServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(ServingConfigServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(ServingConfigServiceClient.parse_common_organization_path) + common_project_path = staticmethod(ServingConfigServiceClient.common_project_path) + parse_common_project_path = staticmethod(ServingConfigServiceClient.parse_common_project_path) + common_location_path = staticmethod(ServingConfigServiceClient.common_location_path) + parse_common_location_path = staticmethod(ServingConfigServiceClient.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: + ServingConfigServiceAsyncClient: The constructed client. + """ + return ServingConfigServiceClient.from_service_account_info.__func__(ServingConfigServiceAsyncClient, 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: + ServingConfigServiceAsyncClient: The constructed client. + """ + return ServingConfigServiceClient.from_service_account_file.__func__(ServingConfigServiceAsyncClient, 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 ServingConfigServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> ServingConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ServingConfigServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(ServingConfigServiceClient).get_transport_class, type(ServingConfigServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, ServingConfigServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the serving config service 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, ~.ServingConfigServiceTransport]): 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 = ServingConfigServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def create_serving_config(self, + request: Optional[Union[serving_config_service.CreateServingConfigRequest, dict]] = None, + *, + parent: Optional[str] = None, + serving_config: Optional[gcr_serving_config.ServingConfig] = None, + serving_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2beta.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2beta.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + .. 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 retail_v2beta + + async def sample_create_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = await client.create_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.CreateServingConfigRequest, dict]]): + The request object. Request for CreateServingConfig + method. + parent (:class:`str`): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config (:class:`google.cloud.retail_v2beta.types.ServingConfig`): + Required. The ServingConfig to + create. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config_id (:class:`str`): + Required. The ID to use for the ServingConfig, which + will become the final component of the ServingConfig's + resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``serving_config_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.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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, serving_config, serving_config_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 = serving_config_service.CreateServingConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if serving_config is not None: + request.serving_config = serving_config + if serving_config_id is not None: + request.serving_config_id = serving_config_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_serving_config, + 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, + ) + + # Done; return the response. + return response + + async def delete_serving_config(self, + request: Optional[Union[serving_config_service.DeleteServingConfigRequest, 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"""Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2beta + + async def sample_delete_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_serving_config(request=request) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.DeleteServingConfigRequest, dict]]): + The request object. Request for DeleteServingConfig + method. + name (:class:`str`): + Required. The resource name of the ServingConfig to + delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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 = serving_config_service.DeleteServingConfigRequest(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_serving_config, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + async def update_serving_config(self, + request: Optional[Union[serving_config_service.UpdateServingConfigRequest, dict]] = None, + *, + serving_config: Optional[gcr_serving_config.ServingConfig] = 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]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Updates a ServingConfig. + + .. 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 retail_v2beta + + async def sample_update_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = await client.update_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.UpdateServingConfigRequest, dict]]): + The request object. Request for UpdateServingConfig + method. + serving_config (:class:`google.cloud.retail_v2beta.types.ServingConfig`): + Required. The ServingConfig to + update. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (:class:`google.protobuf.field_mask_pb2.FieldMask`): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + to update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2beta.ServingConfig.name] + + If not set, all supported fields are updated. + + 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.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_config, 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 = serving_config_service.UpdateServingConfigRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + 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_serving_config, + 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(( + ("serving_config.name", request.serving_config.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def get_serving_config(self, + request: Optional[Union[serving_config_service.GetServingConfigRequest, 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]] = (), + ) -> serving_config.ServingConfig: + r"""Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2beta + + async def sample_get_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.GetServingConfigRequest, dict]]): + The request object. Request for GetServingConfig method. + name (:class:`str`): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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 = serving_config_service.GetServingConfigRequest(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_serving_config, + 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(( + ("name", request.name), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_serving_configs(self, + request: Optional[Union[serving_config_service.ListServingConfigsRequest, 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.ListServingConfigsAsyncPager: + r"""Lists all ServingConfigs linked to this catalog. + + .. 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 retail_v2beta + + async def sample_list_serving_configs(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ListServingConfigsRequest, dict]]): + The request object. Request for ListServingConfigs + method. + parent (:class:`str`): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2beta.services.serving_config_service.pagers.ListServingConfigsAsyncPager: + Response for ListServingConfigs + 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 = serving_config_service.ListServingConfigsRequest(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_serving_configs, + 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, + ) + + # This method is paged; wrap the response in a pager, which provides + # an `__aiter__` convenience method. + response = pagers.ListServingConfigsAsyncPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def add_control(self, + request: Optional[Union[serving_config_service.AddControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + .. 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 retail_v2beta + + async def sample_add_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.add_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.AddControlRequest, dict]]): + The request object. Request for AddControl method. + serving_config (:class:`str`): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 = serving_config_service.AddControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_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.add_control, + 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(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def remove_control(self, + request: Optional[Union[serving_config_service.RemoveControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + .. 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 retail_v2beta + + async def sample_remove_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.remove_control(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.RemoveControlRequest, dict]]): + The request object. Request for RemoveControl method. + serving_config (:class:`str`): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 = serving_config_service.RemoveControlRequest(request) + + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_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.remove_control, + 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(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = await rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "ServingConfigServiceAsyncClient": + 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__ = ( + "ServingConfigServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/client.py new file mode 100644 index 00000000..8ded45b9 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/client.py @@ -0,0 +1,1314 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.services.serving_config_service import pagers +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import search_service +from google.cloud.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config as gcr_serving_config +from google.cloud.retail_v2beta.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from .transports.base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import ServingConfigServiceGrpcTransport +from .transports.grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .transports.rest import ServingConfigServiceRestTransport + + +class ServingConfigServiceClientMeta(type): + """Metaclass for the ServingConfigService 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[ServingConfigServiceTransport]] + _transport_registry["grpc"] = ServingConfigServiceGrpcTransport + _transport_registry["grpc_asyncio"] = ServingConfigServiceGrpcAsyncIOTransport + _transport_registry["rest"] = ServingConfigServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[ServingConfigServiceTransport]: + """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 ServingConfigServiceClient(metaclass=ServingConfigServiceClientMeta): + """Service for modifying ServingConfig.""" + + @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 = "retail.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: + ServingConfigServiceClient: 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: + ServingConfigServiceClient: 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) -> ServingConfigServiceTransport: + """Returns the transport used by the client instance. + + Returns: + ServingConfigServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def serving_config_path(project: str,location: str,catalog: str,serving_config: str,) -> str: + """Returns a fully-qualified serving_config string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + + @staticmethod + def parse_serving_config_path(path: str) -> Dict[str,str]: + """Parses a serving_config path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)/servingConfigs/(?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, ServingConfigServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the serving config service 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, ServingConfigServiceTransport]): 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, ServingConfigServiceTransport): + # transport is a ServingConfigServiceTransport 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_serving_config(self, + request: Optional[Union[serving_config_service.CreateServingConfigRequest, dict]] = None, + *, + parent: Optional[str] = None, + serving_config: Optional[gcr_serving_config.ServingConfig] = None, + serving_config_id: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2beta.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2beta.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + .. 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 retail_v2beta + + def sample_create_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = client.create_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.CreateServingConfigRequest, dict]): + The request object. Request for CreateServingConfig + method. + parent (str): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + + This corresponds to the ``parent`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config (google.cloud.retail_v2beta.types.ServingConfig): + Required. The ServingConfig to + create. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + serving_config_id (str): + Required. The ID to use for the ServingConfig, which + will become the final component of the ServingConfig's + resource name. + + This value should be 4-63 characters, and valid + characters are /[a-z][0-9]-_/. + + This corresponds to the ``serving_config_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.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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, serving_config, serving_config_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 serving_config_service.CreateServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.CreateServingConfigRequest): + request = serving_config_service.CreateServingConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if parent is not None: + request.parent = parent + if serving_config is not None: + request.serving_config = serving_config + if serving_config_id is not None: + request.serving_config_id = serving_config_id + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.create_serving_config] + + # 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_serving_config(self, + request: Optional[Union[serving_config_service.DeleteServingConfigRequest, 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"""Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2beta + + def sample_delete_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_serving_config(request=request) + + Args: + request (Union[google.cloud.retail_v2beta.types.DeleteServingConfigRequest, dict]): + The request object. Request for DeleteServingConfig + method. + name (str): + Required. The resource name of the ServingConfig to + delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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 serving_config_service.DeleteServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.DeleteServingConfigRequest): + request = serving_config_service.DeleteServingConfigRequest(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_serving_config] + + # 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 update_serving_config(self, + request: Optional[Union[serving_config_service.UpdateServingConfigRequest, dict]] = None, + *, + serving_config: Optional[gcr_serving_config.ServingConfig] = 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]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Updates a ServingConfig. + + .. 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 retail_v2beta + + def sample_update_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = client.update_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.UpdateServingConfigRequest, dict]): + The request object. Request for UpdateServingConfig + method. + serving_config (google.cloud.retail_v2beta.types.ServingConfig): + Required. The ServingConfig to + update. + + This corresponds to the ``serving_config`` field + on the ``request`` instance; if ``request`` is provided, this + should not be set. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] + to update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2beta.ServingConfig.name] + + If not set, all supported fields are updated. + + 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.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_config, 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 serving_config_service.UpdateServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.UpdateServingConfigRequest): + request = serving_config_service.UpdateServingConfigRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + 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_serving_config] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config.name", request.serving_config.name), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def get_serving_config(self, + request: Optional[Union[serving_config_service.GetServingConfigRequest, 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]] = (), + ) -> serving_config.ServingConfig: + r"""Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig 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 retail_v2beta + + def sample_get_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_serving_config(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.GetServingConfigRequest, dict]): + The request object. Request for GetServingConfig method. + name (str): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_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.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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 serving_config_service.GetServingConfigRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.GetServingConfigRequest): + request = serving_config_service.GetServingConfigRequest(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_serving_config] + + # 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 list_serving_configs(self, + request: Optional[Union[serving_config_service.ListServingConfigsRequest, 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.ListServingConfigsPager: + r"""Lists all ServingConfigs linked to this catalog. + + .. 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 retail_v2beta + + def sample_list_serving_configs(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ListServingConfigsRequest, dict]): + The request object. Request for ListServingConfigs + method. + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_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.retail_v2beta.services.serving_config_service.pagers.ListServingConfigsPager: + Response for ListServingConfigs + 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 serving_config_service.ListServingConfigsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.ListServingConfigsRequest): + request = serving_config_service.ListServingConfigsRequest(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_serving_configs] + + # 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.ListServingConfigsPager( + method=rpc, + request=request, + response=response, + metadata=metadata, + ) + + # Done; return the response. + return response + + def add_control(self, + request: Optional[Union[serving_config_service.AddControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + .. 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 retail_v2beta + + def sample_add_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.add_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.AddControlRequest, dict]): + The request object. Request for AddControl method. + serving_config (str): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 serving_config_service.AddControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.AddControlRequest): + request = serving_config_service.AddControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.add_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def remove_control(self, + request: Optional[Union[serving_config_service.RemoveControlRequest, dict]] = None, + *, + serving_config: Optional[str] = None, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> gcr_serving_config.ServingConfig: + r"""Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + .. 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 retail_v2beta + + def sample_remove_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.remove_control(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.RemoveControlRequest, dict]): + The request object. Request for RemoveControl method. + serving_config (str): + Required. The source ServingConfig resource name . + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + + This corresponds to the ``serving_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.cloud.retail_v2beta.types.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + # 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([serving_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 serving_config_service.RemoveControlRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, serving_config_service.RemoveControlRequest): + request = serving_config_service.RemoveControlRequest(request) + # If we have keyword arguments corresponding to fields on the + # request, apply these. + if serving_config is not None: + request.serving_config = serving_config + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.remove_control] + + # Certain fields should be provided within the metadata header; + # add these here. + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ("serving_config", request.serving_config), + )), + ) + + # Send the request. + response = rpc( + request, + retry=retry, + timeout=timeout, + metadata=metadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "ServingConfigServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "ServingConfigServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/pagers.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/pagers.py new file mode 100644 index 00000000..7f3f5a0a --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/pagers.py @@ -0,0 +1,140 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config_service + + +class ListServingConfigsPager: + """A pager for iterating through ``list_serving_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListServingConfigsResponse` object, and + provides an ``__iter__`` method to iterate through its + ``serving_configs`` field. + + If there are more pages, the ``__iter__`` method will make additional + ``ListServingConfigs`` requests and continue to iterate + through the ``serving_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListServingConfigsResponse` + 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[..., serving_config_service.ListServingConfigsResponse], + request: serving_config_service.ListServingConfigsRequest, + response: serving_config_service.ListServingConfigsResponse, + *, + 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.retail_v2beta.types.ListServingConfigsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListServingConfigsResponse): + 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 = serving_config_service.ListServingConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + def pages(self) -> Iterator[serving_config_service.ListServingConfigsResponse]: + 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[serving_config.ServingConfig]: + for page in self.pages: + yield from page.serving_configs + + def __repr__(self) -> str: + return '{0}<{1!r}>'.format(self.__class__.__name__, self._response) + + +class ListServingConfigsAsyncPager: + """A pager for iterating through ``list_serving_configs`` requests. + + This class thinly wraps an initial + :class:`google.cloud.retail_v2beta.types.ListServingConfigsResponse` object, and + provides an ``__aiter__`` method to iterate through its + ``serving_configs`` field. + + If there are more pages, the ``__aiter__`` method will make additional + ``ListServingConfigs`` requests and continue to iterate + through the ``serving_configs`` field on the + corresponding responses. + + All the usual :class:`google.cloud.retail_v2beta.types.ListServingConfigsResponse` + 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[serving_config_service.ListServingConfigsResponse]], + request: serving_config_service.ListServingConfigsRequest, + response: serving_config_service.ListServingConfigsResponse, + *, + 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.retail_v2beta.types.ListServingConfigsRequest): + The initial request object. + response (google.cloud.retail_v2beta.types.ListServingConfigsResponse): + 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 = serving_config_service.ListServingConfigsRequest(request) + self._response = response + self._metadata = metadata + + def __getattr__(self, name: str) -> Any: + return getattr(self._response, name) + + @property + async def pages(self) -> AsyncIterator[serving_config_service.ListServingConfigsResponse]: + 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[serving_config.ServingConfig]: + async def async_generator(): + async for page in self.pages: + for response in page.serving_configs: + 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/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/__init__.py new file mode 100644 index 00000000..e0440c46 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/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 ServingConfigServiceTransport +from .grpc import ServingConfigServiceGrpcTransport +from .grpc_asyncio import ServingConfigServiceGrpcAsyncIOTransport +from .rest import ServingConfigServiceRestTransport +from .rest import ServingConfigServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[ServingConfigServiceTransport]] +_transport_registry['grpc'] = ServingConfigServiceGrpcTransport +_transport_registry['grpc_asyncio'] = ServingConfigServiceGrpcAsyncIOTransport +_transport_registry['rest'] = ServingConfigServiceRestTransport + +__all__ = ( + 'ServingConfigServiceTransport', + 'ServingConfigServiceGrpcTransport', + 'ServingConfigServiceGrpcAsyncIOTransport', + 'ServingConfigServiceRestTransport', + 'ServingConfigServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/base.py new file mode 100644 index 00000000..301fb16d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/base.py @@ -0,0 +1,255 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config as gcr_serving_config +from google.cloud.retail_v2beta.types import serving_config_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 ServingConfigServiceTransport(abc.ABC): + """Abstract transport class for ServingConfigService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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_serving_config: gapic_v1.method.wrap_method( + self.create_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.delete_serving_config: gapic_v1.method.wrap_method( + self.delete_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.update_serving_config: gapic_v1.method.wrap_method( + self.update_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.get_serving_config: gapic_v1.method.wrap_method( + self.get_serving_config, + default_timeout=None, + client_info=client_info, + ), + self.list_serving_configs: gapic_v1.method.wrap_method( + self.list_serving_configs, + default_timeout=None, + client_info=client_info, + ), + self.add_control: gapic_v1.method.wrap_method( + self.add_control, + default_timeout=None, + client_info=client_info, + ), + self.remove_control: gapic_v1.method.wrap_method( + self.remove_control, + 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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + Union[ + empty_pb2.Empty, + Awaitable[empty_pb2.Empty] + ]]: + raise NotImplementedError() + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + Union[ + serving_config.ServingConfig, + Awaitable[serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + Union[ + serving_config_service.ListServingConfigsResponse, + Awaitable[serving_config_service.ListServingConfigsResponse] + ]]: + raise NotImplementedError() + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + Union[ + gcr_serving_config.ServingConfig, + Awaitable[gcr_serving_config.ServingConfig] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'ServingConfigServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc.py new file mode 100644 index 00000000..b14790ad --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc.py @@ -0,0 +1,480 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config as gcr_serving_config +from google.cloud.retail_v2beta.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO + + +class ServingConfigServiceGrpcTransport(ServingConfigServiceTransport): + """gRPC backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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 = 'retail.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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the create serving config method over gRPC. + + Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2beta.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2beta.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + Returns: + Callable[[~.CreateServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['create_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/CreateServingConfig', + request_serializer=serving_config_service.CreateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['create_serving_config'] + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + empty_pb2.Empty]: + r"""Return a callable for the delete serving config method over gRPC. + + Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.DeleteServingConfigRequest], + ~.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_serving_config' not in self._stubs: + self._stubs['delete_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/DeleteServingConfig', + request_serializer=serving_config_service.DeleteServingConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_serving_config'] + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the update serving config method over gRPC. + + Updates a ServingConfig. + + Returns: + Callable[[~.UpdateServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['update_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/UpdateServingConfig', + request_serializer=serving_config_service.UpdateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['update_serving_config'] + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + serving_config.ServingConfig]: + r"""Return a callable for the get serving config method over gRPC. + + Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.GetServingConfigRequest], + ~.ServingConfig]: + 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_serving_config' not in self._stubs: + self._stubs['get_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/GetServingConfig', + request_serializer=serving_config_service.GetServingConfigRequest.serialize, + response_deserializer=serving_config.ServingConfig.deserialize, + ) + return self._stubs['get_serving_config'] + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + serving_config_service.ListServingConfigsResponse]: + r"""Return a callable for the list serving configs method over gRPC. + + Lists all ServingConfigs linked to this catalog. + + Returns: + Callable[[~.ListServingConfigsRequest], + ~.ListServingConfigsResponse]: + 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_serving_configs' not in self._stubs: + self._stubs['list_serving_configs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/ListServingConfigs', + request_serializer=serving_config_service.ListServingConfigsRequest.serialize, + response_deserializer=serving_config_service.ListServingConfigsResponse.deserialize, + ) + return self._stubs['list_serving_configs'] + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the add control method over gRPC. + + Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + Returns: + Callable[[~.AddControlRequest], + ~.ServingConfig]: + 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_control' not in self._stubs: + self._stubs['add_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/AddControl', + request_serializer=serving_config_service.AddControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['add_control'] + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + gcr_serving_config.ServingConfig]: + r"""Return a callable for the remove control method over gRPC. + + Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + Returns: + Callable[[~.RemoveControlRequest], + ~.ServingConfig]: + 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_control' not in self._stubs: + self._stubs['remove_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/RemoveControl', + request_serializer=serving_config_service.RemoveControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['remove_control'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'ServingConfigServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..1d41035a --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/grpc_asyncio.py @@ -0,0 +1,479 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config as gcr_serving_config +from google.cloud.retail_v2beta.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import empty_pb2 # type: ignore +from .base import ServingConfigServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import ServingConfigServiceGrpcTransport + + +class ServingConfigServiceGrpcAsyncIOTransport(ServingConfigServiceTransport): + """gRPC AsyncIO backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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 = 'retail.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 create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the create serving config method over gRPC. + + Creates a ServingConfig. + + A maximum of 100 + [ServingConfig][google.cloud.retail.v2beta.ServingConfig]s are + allowed in a [Catalog][google.cloud.retail.v2beta.Catalog], + otherwise a FAILED_PRECONDITION error is returned. + + Returns: + Callable[[~.CreateServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['create_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/CreateServingConfig', + request_serializer=serving_config_service.CreateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['create_serving_config'] + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + Awaitable[empty_pb2.Empty]]: + r"""Return a callable for the delete serving config method over gRPC. + + Deletes a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.DeleteServingConfigRequest], + 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_serving_config' not in self._stubs: + self._stubs['delete_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/DeleteServingConfig', + request_serializer=serving_config_service.DeleteServingConfigRequest.serialize, + response_deserializer=empty_pb2.Empty.FromString, + ) + return self._stubs['delete_serving_config'] + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the update serving config method over gRPC. + + Updates a ServingConfig. + + Returns: + Callable[[~.UpdateServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['update_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/UpdateServingConfig', + request_serializer=serving_config_service.UpdateServingConfigRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['update_serving_config'] + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + Awaitable[serving_config.ServingConfig]]: + r"""Return a callable for the get serving config method over gRPC. + + Gets a ServingConfig. + + Returns a NotFound error if the ServingConfig does not + exist. + + Returns: + Callable[[~.GetServingConfigRequest], + Awaitable[~.ServingConfig]]: + 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_serving_config' not in self._stubs: + self._stubs['get_serving_config'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/GetServingConfig', + request_serializer=serving_config_service.GetServingConfigRequest.serialize, + response_deserializer=serving_config.ServingConfig.deserialize, + ) + return self._stubs['get_serving_config'] + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + Awaitable[serving_config_service.ListServingConfigsResponse]]: + r"""Return a callable for the list serving configs method over gRPC. + + Lists all ServingConfigs linked to this catalog. + + Returns: + Callable[[~.ListServingConfigsRequest], + Awaitable[~.ListServingConfigsResponse]]: + 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_serving_configs' not in self._stubs: + self._stubs['list_serving_configs'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/ListServingConfigs', + request_serializer=serving_config_service.ListServingConfigsRequest.serialize, + response_deserializer=serving_config_service.ListServingConfigsResponse.deserialize, + ) + return self._stubs['list_serving_configs'] + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the add control method over gRPC. + + Enables a Control on the specified ServingConfig. The control is + added in the last position of the list of controls it belongs to + (e.g. if it's a facet spec control it will be applied in the + last position of servingConfig.facetSpecIds) Returns a + ALREADY_EXISTS error if the control has already been applied. + Returns a FAILED_PRECONDITION error if the addition could exceed + maximum number of control allowed for that type of control. + + Returns: + Callable[[~.AddControlRequest], + Awaitable[~.ServingConfig]]: + 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_control' not in self._stubs: + self._stubs['add_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/AddControl', + request_serializer=serving_config_service.AddControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['add_control'] + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + Awaitable[gcr_serving_config.ServingConfig]]: + r"""Return a callable for the remove control method over gRPC. + + Disables a Control on the specified ServingConfig. The control + is removed from the ServingConfig. Returns a NOT_FOUND error if + the Control is not enabled for the ServingConfig. + + Returns: + Callable[[~.RemoveControlRequest], + Awaitable[~.ServingConfig]]: + 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_control' not in self._stubs: + self._stubs['remove_control'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.ServingConfigService/RemoveControl', + request_serializer=serving_config_service.RemoveControlRequest.serialize, + response_deserializer=gcr_serving_config.ServingConfig.deserialize, + ) + return self._stubs['remove_control'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'ServingConfigServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/rest.py new file mode 100644 index 00000000..c1370da0 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/serving_config_service/transports/rest.py @@ -0,0 +1,1182 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.cloud.location import locations_pb2 # type: ignore +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.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config as gcr_serving_config +from google.cloud.retail_v2beta.types import serving_config_service +from google.protobuf import empty_pb2 # type: ignore +from google.longrunning import operations_pb2 # type: ignore + +from .base import ServingConfigServiceTransport, 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 ServingConfigServiceRestInterceptor: + """Interceptor for ServingConfigService. + + 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 ServingConfigServiceRestTransport. + + .. code-block:: python + class MyCustomServingConfigServiceInterceptor(ServingConfigServiceRestInterceptor): + def pre_add_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_add_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_create_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_create_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_delete_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def pre_get_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_get_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_list_serving_configs(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_list_serving_configs(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_remove_control(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_remove_control(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_update_serving_config(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_update_serving_config(self, response): + logging.log(f"Received response: {response}") + return response + + transport = ServingConfigServiceRestTransport(interceptor=MyCustomServingConfigServiceInterceptor()) + client = ServingConfigServiceClient(transport=transport) + + + """ + def pre_add_control(self, request: serving_config_service.AddControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.AddControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for add_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_add_control(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for add_control + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_create_serving_config(self, request: serving_config_service.CreateServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.CreateServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for create_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_create_serving_config(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for create_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_delete_serving_config(self, request: serving_config_service.DeleteServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.DeleteServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for delete_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def pre_get_serving_config(self, request: serving_config_service.GetServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.GetServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_get_serving_config(self, response: serving_config.ServingConfig) -> serving_config.ServingConfig: + """Post-rpc interceptor for get_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_list_serving_configs(self, request: serving_config_service.ListServingConfigsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.ListServingConfigsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_serving_configs + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_list_serving_configs(self, response: serving_config_service.ListServingConfigsResponse) -> serving_config_service.ListServingConfigsResponse: + """Post-rpc interceptor for list_serving_configs + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_remove_control(self, request: serving_config_service.RemoveControlRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.RemoveControlRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for remove_control + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_remove_control(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for remove_control + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_update_serving_config(self, request: serving_config_service.UpdateServingConfigRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[serving_config_service.UpdateServingConfigRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for update_serving_config + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_update_serving_config(self, response: gcr_serving_config.ServingConfig) -> gcr_serving_config.ServingConfig: + """Post-rpc interceptor for update_serving_config + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the ServingConfigService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the ServingConfigService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class ServingConfigServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: ServingConfigServiceRestInterceptor + + +class ServingConfigServiceRestTransport(ServingConfigServiceTransport): + """REST backend transport for ServingConfigService. + + Service for modifying ServingConfig. + + 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 = 'retail.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[ServingConfigServiceRestInterceptor] = 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 ServingConfigServiceRestInterceptor() + self._prep_wrapped_messages(client_info) + + class _AddControl(ServingConfigServiceRestStub): + def __hash__(self): + return hash("AddControl") + + __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: serving_config_service.AddControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the add control method over HTTP. + + Args: + request (~.serving_config_service.AddControlRequest): + The request object. Request for AddControl 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:addControl', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_add_control(request, metadata) + pb_request = serving_config_service.AddControlRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_add_control(resp) + return resp + + class _CreateServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("CreateServingConfig") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "servingConfigId" : "", } + + @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: serving_config_service.CreateServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the create serving config method over HTTP. + + Args: + request (~.serving_config_service.CreateServingConfigRequest): + The request object. Request for CreateServingConfig + 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/servingConfigs', + 'body': 'serving_config', + }, + ] + request, metadata = self._interceptor.pre_create_serving_config(request, metadata) + pb_request = serving_config_service.CreateServingConfigRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_create_serving_config(resp) + return resp + + class _DeleteServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("DeleteServingConfig") + + __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: serving_config_service.DeleteServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ): + r"""Call the delete serving config method over HTTP. + + Args: + request (~.serving_config_service.DeleteServingConfigRequest): + The request object. Request for DeleteServingConfig + 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + }, + ] + request, metadata = self._interceptor.pre_delete_serving_config(request, metadata) + pb_request = serving_config_service.DeleteServingConfigRequest.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 _GetServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("GetServingConfig") + + __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: serving_config_service.GetServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> serving_config.ServingConfig: + r"""Call the get serving config method over HTTP. + + Args: + request (~.serving_config_service.GetServingConfigRequest): + The request object. Request for GetServingConfig 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: + ~.serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + }, + ] + request, metadata = self._interceptor.pre_get_serving_config(request, metadata) + pb_request = serving_config_service.GetServingConfigRequest.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 = serving_config.ServingConfig() + pb_resp = serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_get_serving_config(resp) + return resp + + class _ListServingConfigs(ServingConfigServiceRestStub): + def __hash__(self): + return hash("ListServingConfigs") + + __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: serving_config_service.ListServingConfigsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> serving_config_service.ListServingConfigsResponse: + r"""Call the list serving configs method over HTTP. + + Args: + request (~.serving_config_service.ListServingConfigsRequest): + The request object. Request for ListServingConfigs + 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: + ~.serving_config_service.ListServingConfigsResponse: + Response for ListServingConfigs + method. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/servingConfigs', + }, + ] + request, metadata = self._interceptor.pre_list_serving_configs(request, metadata) + pb_request = serving_config_service.ListServingConfigsRequest.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 = serving_config_service.ListServingConfigsResponse() + pb_resp = serving_config_service.ListServingConfigsResponse.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_list_serving_configs(resp) + return resp + + class _RemoveControl(ServingConfigServiceRestStub): + def __hash__(self): + return hash("RemoveControl") + + __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: serving_config_service.RemoveControlRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the remove control method over HTTP. + + Args: + request (~.serving_config_service.RemoveControlRequest): + The request object. Request for RemoveControl 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:removeControl', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_remove_control(request, metadata) + pb_request = serving_config_service.RemoveControlRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_remove_control(resp) + return resp + + class _UpdateServingConfig(ServingConfigServiceRestStub): + def __hash__(self): + return hash("UpdateServingConfig") + + __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: serving_config_service.UpdateServingConfigRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> gcr_serving_config.ServingConfig: + r"""Call the update serving config method over HTTP. + + Args: + request (~.serving_config_service.UpdateServingConfigRequest): + The request object. Request for UpdateServingConfig + 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: + ~.gcr_serving_config.ServingConfig: + Configures metadata that is used to + generate serving time results (e.g. + search results or recommendation + predictions). + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'patch', + 'uri': '/v2beta/{serving_config.name=projects/*/locations/*/catalogs/*/servingConfigs/*}', + 'body': 'serving_config', + }, + ] + request, metadata = self._interceptor.pre_update_serving_config(request, metadata) + pb_request = serving_config_service.UpdateServingConfigRequest.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 = gcr_serving_config.ServingConfig() + pb_resp = gcr_serving_config.ServingConfig.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_update_serving_config(resp) + return resp + + @property + def add_control(self) -> Callable[ + [serving_config_service.AddControlRequest], + gcr_serving_config.ServingConfig]: + # 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._AddControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def create_serving_config(self) -> Callable[ + [serving_config_service.CreateServingConfigRequest], + gcr_serving_config.ServingConfig]: + # 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._CreateServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def delete_serving_config(self) -> Callable[ + [serving_config_service.DeleteServingConfigRequest], + 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._DeleteServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_serving_config(self) -> Callable[ + [serving_config_service.GetServingConfigRequest], + serving_config.ServingConfig]: + # 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._GetServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def list_serving_configs(self) -> Callable[ + [serving_config_service.ListServingConfigsRequest], + serving_config_service.ListServingConfigsResponse]: + # 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._ListServingConfigs(self._session, self._host, self._interceptor) # type: ignore + + @property + def remove_control(self) -> Callable[ + [serving_config_service.RemoveControlRequest], + gcr_serving_config.ServingConfig]: + # 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._RemoveControl(self._session, self._host, self._interceptor) # type: ignore + + @property + def update_serving_config(self) -> Callable[ + [serving_config_service.UpdateServingConfigRequest], + gcr_serving_config.ServingConfig]: + # 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._UpdateServingConfig(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(ServingConfigServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(ServingConfigServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'ServingConfigServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/__init__.py new file mode 100644 index 00000000..387c002d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/__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 UserEventServiceClient +from .async_client import UserEventServiceAsyncClient + +__all__ = ( + 'UserEventServiceClient', + 'UserEventServiceAsyncClient', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/async_client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/async_client.py new file mode 100644 index 00000000..b7acfb95 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/async_client.py @@ -0,0 +1,865 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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 import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import purge_config +from google.cloud.retail_v2beta.types import user_event +from google.cloud.retail_v2beta.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .client import UserEventServiceClient + + +class UserEventServiceAsyncClient: + """Service for ingesting end user actions on the customer + website. + """ + + _client: UserEventServiceClient + + DEFAULT_ENDPOINT = UserEventServiceClient.DEFAULT_ENDPOINT + DEFAULT_MTLS_ENDPOINT = UserEventServiceClient.DEFAULT_MTLS_ENDPOINT + + catalog_path = staticmethod(UserEventServiceClient.catalog_path) + parse_catalog_path = staticmethod(UserEventServiceClient.parse_catalog_path) + product_path = staticmethod(UserEventServiceClient.product_path) + parse_product_path = staticmethod(UserEventServiceClient.parse_product_path) + common_billing_account_path = staticmethod(UserEventServiceClient.common_billing_account_path) + parse_common_billing_account_path = staticmethod(UserEventServiceClient.parse_common_billing_account_path) + common_folder_path = staticmethod(UserEventServiceClient.common_folder_path) + parse_common_folder_path = staticmethod(UserEventServiceClient.parse_common_folder_path) + common_organization_path = staticmethod(UserEventServiceClient.common_organization_path) + parse_common_organization_path = staticmethod(UserEventServiceClient.parse_common_organization_path) + common_project_path = staticmethod(UserEventServiceClient.common_project_path) + parse_common_project_path = staticmethod(UserEventServiceClient.parse_common_project_path) + common_location_path = staticmethod(UserEventServiceClient.common_location_path) + parse_common_location_path = staticmethod(UserEventServiceClient.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: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_info.__func__(UserEventServiceAsyncClient, 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: + UserEventServiceAsyncClient: The constructed client. + """ + return UserEventServiceClient.from_service_account_file.__func__(UserEventServiceAsyncClient, 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 UserEventServiceClient.get_mtls_endpoint_and_cert_source(client_options) # type: ignore + + @property + def transport(self) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client instance. + """ + return self._client.transport + + get_transport_class = functools.partial(type(UserEventServiceClient).get_transport_class, type(UserEventServiceClient)) + + def __init__(self, *, + credentials: Optional[ga_credentials.Credentials] = None, + transport: Union[str, UserEventServiceTransport] = "grpc_asyncio", + client_options: Optional[ClientOptions] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service 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, ~.UserEventServiceTransport]): 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 = UserEventServiceClient( + credentials=credentials, + transport=transport, + client_options=client_options, + client_info=client_info, + + ) + + async def write_user_event(self, + request: Optional[Union[user_event_service.WriteUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + .. 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 retail_v2beta + + async def sample_write_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = await client.write_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.WriteUserEventRequest, dict]]): + The request object. Request message for WriteUserEvent + 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: + google.cloud.retail_v2beta.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.write_user_event, + 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, + ) + + # Done; return the response. + return response + + async def collect_user_event(self, + request: Optional[Union[user_event_service.CollectUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + .. 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 retail_v2beta + + async def sample_collect_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = await client.collect_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.CollectUserEventRequest, dict]]): + The request object. Request message for CollectUserEvent + 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: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.collect_user_event, + 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, + ) + + # Done; return the response. + return response + + async def purge_user_events(self, + request: Optional[Union[purge_config.PurgeUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + .. 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 retail_v2beta + + async def sample_purge_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.PurgeUserEventsRequest, dict]]): + The request object. Request message for PurgeUserEvents + 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: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + request = purge_config.PurgeUserEventsRequest(request) + + # 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_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.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, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + async def import_user_events(self, + request: Optional[Union[import_config.ImportUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + .. 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 retail_v2beta + + async def sample_import_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2beta.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2beta.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.ImportUserEventsRequest, dict]]): + The request object. Request message for the + ImportUserEvents request. + 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.retail_v2beta.types.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + request = import_config.ImportUserEventsRequest(request) + + # 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_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.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, + ) + + # Wrap the response in an operation future. + response = operation_async.from_gapic( + response, + self._client._transport.operations_client, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + async def rejoin_user_events(self, + request: Optional[Union[user_event_service.RejoinUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation_async.AsyncOperation: + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + .. 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 retail_v2beta + + async def sample_rejoin_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + + Args: + request (Optional[Union[google.cloud.retail_v2beta.types.RejoinUserEventsRequest, dict]]): + The request object. Request message for RejoinUserEvents + 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: + google.api_core.operation_async.AsyncOperation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2beta.types.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method_async.wrap_method( + self._client._transport.rejoin_user_events, + 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, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + async def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._client._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = await rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + async def __aenter__(self) -> "UserEventServiceAsyncClient": + 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__ = ( + "UserEventServiceAsyncClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/client.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/client.py new file mode 100644 index 00000000..67e8d2c3 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/client.py @@ -0,0 +1,1072 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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 import httpbody_pb2 # type: ignore +from google.api_core import operation # type: ignore +from google.api_core import operation_async # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import purge_config +from google.cloud.retail_v2beta.types import user_event +from google.cloud.retail_v2beta.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from google.protobuf import any_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from .transports.base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .transports.grpc import UserEventServiceGrpcTransport +from .transports.grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .transports.rest import UserEventServiceRestTransport + + +class UserEventServiceClientMeta(type): + """Metaclass for the UserEventService 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[UserEventServiceTransport]] + _transport_registry["grpc"] = UserEventServiceGrpcTransport + _transport_registry["grpc_asyncio"] = UserEventServiceGrpcAsyncIOTransport + _transport_registry["rest"] = UserEventServiceRestTransport + + def get_transport_class(cls, + label: Optional[str] = None, + ) -> Type[UserEventServiceTransport]: + """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 UserEventServiceClient(metaclass=UserEventServiceClientMeta): + """Service for ingesting end user actions on the customer + website. + """ + + @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 = "retail.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: + UserEventServiceClient: 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: + UserEventServiceClient: 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) -> UserEventServiceTransport: + """Returns the transport used by the client instance. + + Returns: + UserEventServiceTransport: The transport used by the client + instance. + """ + return self._transport + + @staticmethod + def catalog_path(project: str,location: str,catalog: str,) -> str: + """Returns a fully-qualified catalog string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + + @staticmethod + def parse_catalog_path(path: str) -> Dict[str,str]: + """Parses a catalog path into its component segments.""" + m = re.match(r"^projects/(?P.+?)/locations/(?P.+?)/catalogs/(?P.+?)$", path) + return m.groupdict() if m else {} + + @staticmethod + def product_path(project: str,location: str,catalog: str,branch: str,product: str,) -> str: + """Returns a fully-qualified product string.""" + return "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, 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.+?)/catalogs/(?P.+?)/branches/(?P.+?)/products/(?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, UserEventServiceTransport]] = None, + client_options: Optional[Union[client_options_lib.ClientOptions, dict]] = None, + client_info: gapic_v1.client_info.ClientInfo = DEFAULT_CLIENT_INFO, + ) -> None: + """Instantiates the user event service 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, UserEventServiceTransport]): 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, UserEventServiceTransport): + # transport is a UserEventServiceTransport 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 write_user_event(self, + request: Optional[Union[user_event_service.WriteUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> user_event.UserEvent: + r"""Writes a single user event. + + .. 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 retail_v2beta + + def sample_write_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = client.write_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.WriteUserEventRequest, dict]): + The request object. Request message for WriteUserEvent + 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: + google.cloud.retail_v2beta.types.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.WriteUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.WriteUserEventRequest): + request = user_event_service.WriteUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.write_user_event] + + # 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 collect_user_event(self, + request: Optional[Union[user_event_service.CollectUserEventRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> httpbody_pb2.HttpBody: + r"""Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + .. 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 retail_v2beta + + def sample_collect_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = client.collect_user_event(request=request) + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.CollectUserEventRequest, dict]): + The request object. Request message for CollectUserEvent + 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: + google.api.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It should only be used for + payload formats that can't be represented as JSON, + such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as + the response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request + fields and also want access to the raw HTTP body. + + Example: + + message GetResourceRequest { + // A unique request id. string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.CollectUserEventRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.CollectUserEventRequest): + request = user_event_service.CollectUserEventRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.collect_user_event] + + # 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 purge_user_events(self, + request: Optional[Union[purge_config.PurgeUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + .. 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 retail_v2beta + + def sample_purge_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.PurgeUserEventsRequest, dict]): + The request object. Request message for PurgeUserEvents + 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: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be :class:`google.cloud.retail_v2beta.types.PurgeUserEventsResponse` Response of the PurgeUserEventsRequest. If the long running operation is + successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a purge_config.PurgeUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, purge_config.PurgeUserEventsRequest): + request = purge_config.PurgeUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.purge_user_events] + + # 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, + purge_config.PurgeUserEventsResponse, + metadata_type=purge_config.PurgeMetadata, + ) + + # Done; return the response. + return response + + def import_user_events(self, + request: Optional[Union[import_config.ImportUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + .. 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 retail_v2beta + + def sample_import_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + input_config = retail_v2beta.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2beta.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.ImportUserEventsRequest, dict]): + The request object. Request message for the + ImportUserEvents request. + 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.retail_v2beta.types.ImportUserEventsResponse` Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is + returned by the + google.longrunning.Operations.response field if the + operation was successful. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a import_config.ImportUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, import_config.ImportUserEventsRequest): + request = import_config.ImportUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.import_user_events] + + # 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, + import_config.ImportUserEventsResponse, + metadata_type=import_config.ImportMetadata, + ) + + # Done; return the response. + return response + + def rejoin_user_events(self, + request: Optional[Union[user_event_service.RejoinUserEventsRequest, dict]] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operation.Operation: + r"""Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + .. 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 retail_v2beta + + def sample_rejoin_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + + Args: + request (Union[google.cloud.retail_v2beta.types.RejoinUserEventsRequest, dict]): + The request object. Request message for RejoinUserEvents + 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: + google.api_core.operation.Operation: + An object representing a long-running operation. + + The result type for the operation will be + :class:`google.cloud.retail_v2beta.types.RejoinUserEventsResponse` + Response message for RejoinUserEvents method. + + """ + # Create or coerce a protobuf request object. + # Minor optimization to avoid making a copy if the user passes + # in a user_event_service.RejoinUserEventsRequest. + # There's no risk of modifying the input as we've already verified + # there are no flattened fields. + if not isinstance(request, user_event_service.RejoinUserEventsRequest): + request = user_event_service.RejoinUserEventsRequest(request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = self._transport._wrapped_methods[self._transport.rejoin_user_events] + + # 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, + user_event_service.RejoinUserEventsResponse, + metadata_type=user_event_service.RejoinUserEventsMetadata, + ) + + # Done; return the response. + return response + + def __enter__(self) -> "UserEventServiceClient": + 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() + + def list_operations( + self, + request: Optional[operations_pb2.ListOperationsRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.ListOperationsResponse: + r"""Lists operations that match the specified filter in the request. + + Args: + request (:class:`~.operations_pb2.ListOperationsRequest`): + The request object. Request message for + `ListOperations` 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.ListOperationsResponse: + Response message for ``ListOperations`` method. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.ListOperationsRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.list_operations, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + def get_operation( + self, + request: Optional[operations_pb2.GetOperationRequest] = None, + *, + retry: OptionalRetry = gapic_v1.method.DEFAULT, + timeout: Union[float, object] = gapic_v1.method.DEFAULT, + metadata: Sequence[Tuple[str, str]] = (), + ) -> operations_pb2.Operation: + r"""Gets the latest state of a long-running operation. + + Args: + request (:class:`~.operations_pb2.GetOperationRequest`): + The request object. Request message for + `GetOperation` 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: + An ``Operation`` object. + """ + # Create or coerce a protobuf request object. + # The request isn't a proto-plus wrapped type, + # so it must be constructed via keyword expansion. + if isinstance(request, dict): + request = operations_pb2.GetOperationRequest(**request) + + # Wrap the RPC method; this adds retry and timeout information, + # and friendly error handling. + rpc = gapic_v1.method.wrap_method( + self._transport.get_operation, + 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( + (("name", request.name),)), + ) + + # Send the request. + response = rpc( + request, retry=retry, timeout=timeout, metadata=metadata,) + + # Done; return the response. + return response + + + + + + + + + + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +__all__ = ( + "UserEventServiceClient", +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/__init__.py new file mode 100644 index 00000000..bea95d5a --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/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 UserEventServiceTransport +from .grpc import UserEventServiceGrpcTransport +from .grpc_asyncio import UserEventServiceGrpcAsyncIOTransport +from .rest import UserEventServiceRestTransport +from .rest import UserEventServiceRestInterceptor + + +# Compile a registry of transports. +_transport_registry = OrderedDict() # type: Dict[str, Type[UserEventServiceTransport]] +_transport_registry['grpc'] = UserEventServiceGrpcTransport +_transport_registry['grpc_asyncio'] = UserEventServiceGrpcAsyncIOTransport +_transport_registry['rest'] = UserEventServiceRestTransport + +__all__ = ( + 'UserEventServiceTransport', + 'UserEventServiceGrpcTransport', + 'UserEventServiceGrpcAsyncIOTransport', + 'UserEventServiceRestTransport', + 'UserEventServiceRestInterceptor', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/base.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/base.py new file mode 100644 index 00000000..1fea4356 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/base.py @@ -0,0 +1,248 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta 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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import purge_config +from google.cloud.retail_v2beta.types import user_event +from google.cloud.retail_v2beta.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore + +DEFAULT_CLIENT_INFO = gapic_v1.client_info.ClientInfo(gapic_version=package_version.__version__) + + +class UserEventServiceTransport(abc.ABC): + """Abstract transport class for UserEventService.""" + + AUTH_SCOPES = ( + 'https://www.googleapis.com/auth/cloud-platform', + ) + + DEFAULT_HOST: str = 'retail.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.write_user_event: gapic_v1.method.wrap_method( + self.write_user_event, + default_timeout=None, + client_info=client_info, + ), + self.collect_user_event: gapic_v1.method.wrap_method( + self.collect_user_event, + default_timeout=None, + client_info=client_info, + ), + self.purge_user_events: gapic_v1.method.wrap_method( + self.purge_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=30.0,multiplier=1.3, predicate=retries.if_exception_type( + core_exceptions.DeadlineExceeded, + core_exceptions.ServiceUnavailable, + ), + deadline=30.0, + ), + default_timeout=30.0, + client_info=client_info, + ), + self.import_user_events: gapic_v1.method.wrap_method( + self.import_user_events, + default_retry=retries.Retry( +initial=0.1,maximum=300.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.rejoin_user_events: gapic_v1.method.wrap_method( + self.rejoin_user_events, + 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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Union[ + user_event.UserEvent, + Awaitable[user_event.UserEvent] + ]]: + raise NotImplementedError() + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Union[ + httpbody_pb2.HttpBody, + Awaitable[httpbody_pb2.HttpBody] + ]]: + raise NotImplementedError() + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Union[ + operations_pb2.Operation, + Awaitable[operations_pb2.Operation] + ]]: + raise NotImplementedError() + + @property + def list_operations( + self, + ) -> Callable[ + [operations_pb2.ListOperationsRequest], + Union[operations_pb2.ListOperationsResponse, Awaitable[operations_pb2.ListOperationsResponse]], + ]: + raise NotImplementedError() + + @property + def get_operation( + self, + ) -> Callable[ + [operations_pb2.GetOperationRequest], + Union[operations_pb2.Operation, Awaitable[operations_pb2.Operation]], + ]: + raise NotImplementedError() + + @property + def kind(self) -> str: + raise NotImplementedError() + + +__all__ = ( + 'UserEventServiceTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py new file mode 100644 index 00000000..a1f9a80d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc.py @@ -0,0 +1,455 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import purge_config +from google.cloud.retail_v2beta.types import user_event +from google.cloud.retail_v2beta.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO + + +class UserEventServiceGrpcTransport(UserEventServiceTransport): + """gRPC backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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 = 'retail.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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + user_event.UserEvent]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + ~.UserEvent]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + httpbody_pb2.HttpBody]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + ~.HttpBody]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + ~.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_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + Returns: + Callable[[~.ImportUserEventsRequest], + ~.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_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + operations_pb2.Operation]: + r"""Return a callable for the rejoin user events method over gRPC. + + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + Returns: + Callable[[~.RejoinUserEventsRequest], + ~.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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + @property + def kind(self) -> str: + return "grpc" + + +__all__ = ( + 'UserEventServiceGrpcTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.py new file mode 100644 index 00000000..caa8b727 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/grpc_asyncio.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. +# +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.api import httpbody_pb2 # type: ignore +from google.cloud.location import locations_pb2 # type: ignore +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import purge_config +from google.cloud.retail_v2beta.types import user_event +from google.cloud.retail_v2beta.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore +from .base import UserEventServiceTransport, DEFAULT_CLIENT_INFO +from .grpc import UserEventServiceGrpcTransport + + +class UserEventServiceGrpcAsyncIOTransport(UserEventServiceTransport): + """gRPC AsyncIO backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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 = 'retail.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 write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + Awaitable[user_event.UserEvent]]: + r"""Return a callable for the write user event method over gRPC. + + Writes a single user event. + + Returns: + Callable[[~.WriteUserEventRequest], + Awaitable[~.UserEvent]]: + 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 'write_user_event' not in self._stubs: + self._stubs['write_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/WriteUserEvent', + request_serializer=user_event_service.WriteUserEventRequest.serialize, + response_deserializer=user_event.UserEvent.deserialize, + ) + return self._stubs['write_user_event'] + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + Awaitable[httpbody_pb2.HttpBody]]: + r"""Return a callable for the collect user event method over gRPC. + + Writes a single user event from the browser. This + uses a GET request to due to browser restriction of + POST-ing to a 3rd party domain. + + This method is used only by the Retail API JavaScript + pixel and Google Tag Manager. Users should not call this + method directly. + + Returns: + Callable[[~.CollectUserEventRequest], + Awaitable[~.HttpBody]]: + 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 'collect_user_event' not in self._stubs: + self._stubs['collect_user_event'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/CollectUserEvent', + request_serializer=user_event_service.CollectUserEventRequest.serialize, + response_deserializer=httpbody_pb2.HttpBody.FromString, + ) + return self._stubs['collect_user_event'] + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the purge user events method over gRPC. + + Deletes permanently all user events specified by the + filter provided. Depending on the number of events + specified by the filter, this operation could take hours + or days to complete. To test a filter, use the list + command first. + + Returns: + Callable[[~.PurgeUserEventsRequest], + 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_user_events' not in self._stubs: + self._stubs['purge_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/PurgeUserEvents', + request_serializer=purge_config.PurgeUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['purge_user_events'] + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the import user events method over gRPC. + + Bulk import of User events. Request processing might be + synchronous. Events that already exist are skipped. Use this + method for backfilling historical user events. + + ``Operation.response`` is of type ``ImportResponse``. Note that + it is possible for a subset of the items to be successfully + inserted. ``Operation.metadata`` is of type ``ImportMetadata``. + + Returns: + Callable[[~.ImportUserEventsRequest], + 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_user_events' not in self._stubs: + self._stubs['import_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/ImportUserEvents', + request_serializer=import_config.ImportUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['import_user_events'] + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + Awaitable[operations_pb2.Operation]]: + r"""Return a callable for the rejoin user events method over gRPC. + + Starts a user-event rejoin operation with latest + product catalog. Events are not annotated with detailed + product information for products that are missing from + the catalog when the user event is ingested. These + events are stored as unjoined events with limited usage + on training and serving. You can use this method to + start a join operation on specified events with the + latest version of product catalog. You can also use this + method to correct events joined with the wrong product + catalog. A rejoin operation can take hours or days to + complete. + + Returns: + Callable[[~.RejoinUserEventsRequest], + 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 'rejoin_user_events' not in self._stubs: + self._stubs['rejoin_user_events'] = self.grpc_channel.unary_unary( + '/google.cloud.retail.v2beta.UserEventService/RejoinUserEvents', + request_serializer=user_event_service.RejoinUserEventsRequest.serialize, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs['rejoin_user_events'] + + def close(self): + return self.grpc_channel.close() + + @property + def get_operation( + self, + ) -> Callable[[operations_pb2.GetOperationRequest], operations_pb2.Operation]: + r"""Return a callable for the get_operation method over gRPC. + """ + # 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_operation" not in self._stubs: + self._stubs["get_operation"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/GetOperation", + request_serializer=operations_pb2.GetOperationRequest.SerializeToString, + response_deserializer=operations_pb2.Operation.FromString, + ) + return self._stubs["get_operation"] + + @property + def list_operations( + self, + ) -> Callable[[operations_pb2.ListOperationsRequest], operations_pb2.ListOperationsResponse]: + r"""Return a callable for the list_operations method over gRPC. + """ + # 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_operations" not in self._stubs: + self._stubs["list_operations"] = self.grpc_channel.unary_unary( + "/google.longrunning.Operations/ListOperations", + request_serializer=operations_pb2.ListOperationsRequest.SerializeToString, + response_deserializer=operations_pb2.ListOperationsResponse.FromString, + ) + return self._stubs["list_operations"] + + +__all__ = ( + 'UserEventServiceGrpcAsyncIOTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/rest.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/rest.py new file mode 100644 index 00000000..f76a69e1 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/services/user_event_service/transports/rest.py @@ -0,0 +1,1082 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 google.cloud.location import locations_pb2 # type: ignore +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.api import httpbody_pb2 # type: ignore +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import purge_config +from google.cloud.retail_v2beta.types import user_event +from google.cloud.retail_v2beta.types import user_event_service +from google.longrunning import operations_pb2 # type: ignore + +from .base import UserEventServiceTransport, 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 UserEventServiceRestInterceptor: + """Interceptor for UserEventService. + + 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 UserEventServiceRestTransport. + + .. code-block:: python + class MyCustomUserEventServiceInterceptor(UserEventServiceRestInterceptor): + def pre_collect_user_event(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_collect_user_event(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_import_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_import_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_purge_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_purge_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_rejoin_user_events(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_rejoin_user_events(self, response): + logging.log(f"Received response: {response}") + return response + + def pre_write_user_event(self, request, metadata): + logging.log(f"Received request: {request}") + return request, metadata + + def post_write_user_event(self, response): + logging.log(f"Received response: {response}") + return response + + transport = UserEventServiceRestTransport(interceptor=MyCustomUserEventServiceInterceptor()) + client = UserEventServiceClient(transport=transport) + + + """ + def pre_collect_user_event(self, request: user_event_service.CollectUserEventRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.CollectUserEventRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for collect_user_event + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_collect_user_event(self, response: httpbody_pb2.HttpBody) -> httpbody_pb2.HttpBody: + """Post-rpc interceptor for collect_user_event + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_import_user_events(self, request: import_config.ImportUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[import_config.ImportUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for import_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_import_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for import_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_purge_user_events(self, request: purge_config.PurgeUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[purge_config.PurgeUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for purge_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_purge_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for purge_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_rejoin_user_events(self, request: user_event_service.RejoinUserEventsRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.RejoinUserEventsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for rejoin_user_events + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_rejoin_user_events(self, response: operations_pb2.Operation) -> operations_pb2.Operation: + """Post-rpc interceptor for rejoin_user_events + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_write_user_event(self, request: user_event_service.WriteUserEventRequest, metadata: Sequence[Tuple[str, str]]) -> Tuple[user_event_service.WriteUserEventRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for write_user_event + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_write_user_event(self, response: user_event.UserEvent) -> user_event.UserEvent: + """Post-rpc interceptor for write_user_event + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + + def pre_get_operation( + self, request: operations_pb2.GetOperationRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.GetOperationRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for get_operation + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_get_operation( + self, response: operations_pb2.Operation + ) -> operations_pb2.Operation: + """Post-rpc interceptor for get_operation + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + def pre_list_operations( + self, request: operations_pb2.ListOperationsRequest, metadata: Sequence[Tuple[str, str]] + ) -> Tuple[operations_pb2.ListOperationsRequest, Sequence[Tuple[str, str]]]: + """Pre-rpc interceptor for list_operations + + Override in a subclass to manipulate the request or metadata + before they are sent to the UserEventService server. + """ + return request, metadata + + def post_list_operations( + self, response: operations_pb2.ListOperationsResponse + ) -> operations_pb2.ListOperationsResponse: + """Post-rpc interceptor for list_operations + + Override in a subclass to manipulate the response + after it is returned by the UserEventService server but before + it is returned to user code. + """ + return response + + +@dataclasses.dataclass +class UserEventServiceRestStub: + _session: AuthorizedSession + _host: str + _interceptor: UserEventServiceRestInterceptor + + +class UserEventServiceRestTransport(UserEventServiceTransport): + """REST backend transport for UserEventService. + + Service for ingesting end user actions on the customer + website. + + 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 = 'retail.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[UserEventServiceRestInterceptor] = 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 UserEventServiceRestInterceptor() + 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': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ], + 'google.longrunning.Operations.ListOperations': [ + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, + { + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/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="v2beta") + + self._operations_client = operations_v1.AbstractOperationsClient(transport=rest_transport) + + # Return the client from cache. + return self._operations_client + + class _CollectUserEvent(UserEventServiceRestStub): + def __hash__(self): + return hash("CollectUserEvent") + + __REQUIRED_FIELDS_DEFAULT_VALUES: Dict[str, Any] = { + "userEvent" : "", } + + @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: user_event_service.CollectUserEventRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> httpbody_pb2.HttpBody: + r"""Call the collect user event method over HTTP. + + Args: + request (~.user_event_service.CollectUserEventRequest): + The request object. Request message for CollectUserEvent + 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: + ~.httpbody_pb2.HttpBody: + Message that represents an arbitrary HTTP body. It + should only be used for payload formats that can't be + represented as JSON, such as raw binary or an HTML page. + + This message can be used both in streaming and + non-streaming API methods in the request as well as the + response. + + It can be used as a top-level request field, which is + convenient if one wants to extract parameters from + either the URL or HTTP template into the request fields + and also want access to the raw HTTP body. + + Example: + + :: + + message GetResourceRequest { + // A unique request id. + string request_id = 1; + + // The raw HTTP body is bound to this field. + google.api.HttpBody http_body = 2; + + } + + service ResourceService { + rpc GetResource(GetResourceRequest) + returns (google.api.HttpBody); + rpc UpdateResource(google.api.HttpBody) + returns (google.protobuf.Empty); + + } + + Example with streaming methods: + + :: + + service CaldavService { + rpc GetCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + rpc UpdateCalendar(stream google.api.HttpBody) + returns (stream google.api.HttpBody); + + } + + Use of this type only changes how the request and + response bodies are handled, all other features will + continue to work unchanged. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/userEvents:collect', + }, + ] + request, metadata = self._interceptor.pre_collect_user_event(request, metadata) + pb_request = user_event_service.CollectUserEventRequest.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 = httpbody_pb2.HttpBody() + pb_resp = resp + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_collect_user_event(resp) + return resp + + class _ImportUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("ImportUserEvents") + + __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: import_config.ImportUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the import user events method over HTTP. + + Args: + request (~.import_config.ImportUserEventsRequest): + The request object. Request message for the + ImportUserEvents request. + 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': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/userEvents:import', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_import_user_events(request, metadata) + pb_request = import_config.ImportUserEventsRequest.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_user_events(resp) + return resp + + class _PurgeUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("PurgeUserEvents") + + __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: purge_config.PurgeUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the purge user events method over HTTP. + + Args: + request (~.purge_config.PurgeUserEventsRequest): + The request object. Request message for PurgeUserEvents + 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': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/userEvents:purge', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_purge_user_events(request, metadata) + pb_request = purge_config.PurgeUserEventsRequest.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_user_events(resp) + return resp + + class _RejoinUserEvents(UserEventServiceRestStub): + def __hash__(self): + return hash("RejoinUserEvents") + + __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: user_event_service.RejoinUserEventsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + r"""Call the rejoin user events method over HTTP. + + Args: + request (~.user_event_service.RejoinUserEventsRequest): + The request object. Request message for RejoinUserEvents + 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': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/userEvents:rejoin', + 'body': '*', + }, + ] + request, metadata = self._interceptor.pre_rejoin_user_events(request, metadata) + pb_request = user_event_service.RejoinUserEventsRequest.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_rejoin_user_events(resp) + return resp + + class _WriteUserEvent(UserEventServiceRestStub): + def __hash__(self): + return hash("WriteUserEvent") + + __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: user_event_service.WriteUserEventRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> user_event.UserEvent: + r"""Call the write user event method over HTTP. + + Args: + request (~.user_event_service.WriteUserEventRequest): + The request object. Request message for WriteUserEvent + 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: + ~.user_event.UserEvent: + UserEvent captures all metadata + information Retail API needs to know + about how end users interact with + customers' website. + + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'post', + 'uri': '/v2beta/{parent=projects/*/locations/*/catalogs/*}/userEvents:write', + 'body': 'user_event', + }, + ] + request, metadata = self._interceptor.pre_write_user_event(request, metadata) + pb_request = user_event_service.WriteUserEventRequest.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 = user_event.UserEvent() + pb_resp = user_event.UserEvent.pb(resp) + + json_format.Parse(response.content, pb_resp, ignore_unknown_fields=True) + resp = self._interceptor.post_write_user_event(resp) + return resp + + @property + def collect_user_event(self) -> Callable[ + [user_event_service.CollectUserEventRequest], + httpbody_pb2.HttpBody]: + # 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._CollectUserEvent(self._session, self._host, self._interceptor) # type: ignore + + @property + def import_user_events(self) -> Callable[ + [import_config.ImportUserEventsRequest], + 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._ImportUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def purge_user_events(self) -> Callable[ + [purge_config.PurgeUserEventsRequest], + 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._PurgeUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def rejoin_user_events(self) -> Callable[ + [user_event_service.RejoinUserEventsRequest], + 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._RejoinUserEvents(self._session, self._host, self._interceptor) # type: ignore + + @property + def write_user_event(self) -> Callable[ + [user_event_service.WriteUserEventRequest], + user_event.UserEvent]: + # 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._WriteUserEvent(self._session, self._host, self._interceptor) # type: ignore + + @property + def get_operation(self): + return self._GetOperation(self._session, self._host, self._interceptor) # type: ignore + + class _GetOperation(UserEventServiceRestStub): + def __call__(self, + request: operations_pb2.GetOperationRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.Operation: + + r"""Call the get operation method over HTTP. + + Args: + request (operations_pb2.GetOperationRequest): + The request object for GetOperation 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: Response from GetOperation method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/operations/*}', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/operations/*}', + }, + ] + + request, metadata = self._interceptor.pre_get_operation(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.Operation() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_get_operation(resp) + return resp + + @property + def list_operations(self): + return self._ListOperations(self._session, self._host, self._interceptor) # type: ignore + + class _ListOperations(UserEventServiceRestStub): + def __call__(self, + request: operations_pb2.ListOperationsRequest, *, + retry: OptionalRetry=gapic_v1.method.DEFAULT, + timeout: Optional[float]=None, + metadata: Sequence[Tuple[str, str]]=(), + ) -> operations_pb2.ListOperationsResponse: + + r"""Call the list operations method over HTTP. + + Args: + request (operations_pb2.ListOperationsRequest): + The request object for ListOperations 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.ListOperationsResponse: Response from ListOperations method. + """ + + http_options: List[Dict[str, str]] = [{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*/catalogs/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*/locations/*}/operations', + }, +{ + 'method': 'get', + 'uri': '/v2beta/{name=projects/*}/operations', + }, + ] + + request, metadata = self._interceptor.pre_list_operations(request, metadata) + request_kwargs = json_format.MessageToDict(request) + transcoded_request = path_template.transcode( + http_options, **request_kwargs) + + uri = transcoded_request['uri'] + method = transcoded_request['method'] + + # Jsonify the query params + query_params = json.loads(json.dumps(transcoded_request['query_params'])) + + # 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), + ) + + # In case of error, raise the appropriate core_exceptions.GoogleAPICallError exception + # subclass. + if response.status_code >= 400: + raise core_exceptions.from_http_response(response) + + resp = operations_pb2.ListOperationsResponse() + resp = json_format.Parse(response.content.decode("utf-8"), resp) + resp = self._interceptor.post_list_operations(resp) + return resp + + @property + def kind(self) -> str: + return "rest" + + def close(self): + self._session.close() + + +__all__=( + 'UserEventServiceRestTransport', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/__init__.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/__init__.py new file mode 100644 index 00000000..62b60f2f --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/__init__.py @@ -0,0 +1,324 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 .catalog import ( + AttributesConfig, + Catalog, + CatalogAttribute, + CompletionConfig, + MerchantCenterFeedFilter, + MerchantCenterLink, + MerchantCenterLinkingConfig, + ProductLevelConfig, +) +from .catalog_service import ( + AddCatalogAttributeRequest, + BatchRemoveCatalogAttributesRequest, + BatchRemoveCatalogAttributesResponse, + GetAttributesConfigRequest, + GetCompletionConfigRequest, + GetDefaultBranchRequest, + GetDefaultBranchResponse, + ListCatalogsRequest, + ListCatalogsResponse, + RemoveCatalogAttributeRequest, + ReplaceCatalogAttributeRequest, + SetDefaultBranchRequest, + UpdateAttributesConfigRequest, + UpdateCatalogRequest, + UpdateCompletionConfigRequest, +) +from .common import ( + Audience, + ColorInfo, + Condition, + CustomAttribute, + FulfillmentInfo, + Image, + Interval, + LocalInventory, + PriceInfo, + Rating, + Rule, + UserInfo, + AttributeConfigLevel, + RecommendationsFilteringOption, + SearchSolutionUseCase, + SolutionType, +) +from .completion_service import ( + CompleteQueryRequest, + CompleteQueryResponse, +) +from .control import ( + Control, +) +from .control_service import ( + CreateControlRequest, + DeleteControlRequest, + GetControlRequest, + ListControlsRequest, + ListControlsResponse, + UpdateControlRequest, +) +from .export_config import ( + BigQueryOutputResult, + ExportErrorsConfig, + ExportMetadata, + ExportProductsResponse, + ExportUserEventsResponse, + GcsOutputResult, + OutputResult, +) +from .import_config import ( + BigQuerySource, + CompletionDataInputConfig, + GcsSource, + ImportCompletionDataRequest, + ImportCompletionDataResponse, + ImportErrorsConfig, + ImportMetadata, + ImportProductsRequest, + ImportProductsResponse, + ImportUserEventsRequest, + ImportUserEventsResponse, + ProductInlineSource, + ProductInputConfig, + UserEventImportSummary, + UserEventInlineSource, + UserEventInputConfig, +) +from .model import ( + Model, +) +from .model_service import ( + CreateModelMetadata, + CreateModelRequest, + DeleteModelRequest, + GetModelRequest, + ListModelsRequest, + ListModelsResponse, + PauseModelRequest, + ResumeModelRequest, + TuneModelMetadata, + TuneModelRequest, + TuneModelResponse, + UpdateModelRequest, +) +from .prediction_service import ( + PredictRequest, + PredictResponse, +) +from .product import ( + Product, +) +from .product_service import ( + AddFulfillmentPlacesMetadata, + AddFulfillmentPlacesRequest, + AddFulfillmentPlacesResponse, + AddLocalInventoriesMetadata, + AddLocalInventoriesRequest, + AddLocalInventoriesResponse, + CreateProductRequest, + DeleteProductRequest, + GetProductRequest, + ListProductsRequest, + ListProductsResponse, + RemoveFulfillmentPlacesMetadata, + RemoveFulfillmentPlacesRequest, + RemoveFulfillmentPlacesResponse, + RemoveLocalInventoriesMetadata, + RemoveLocalInventoriesRequest, + RemoveLocalInventoriesResponse, + SetInventoryMetadata, + SetInventoryRequest, + SetInventoryResponse, + UpdateProductRequest, +) +from .promotion import ( + Promotion, +) +from .purge_config import ( + PurgeMetadata, + PurgeUserEventsRequest, + PurgeUserEventsResponse, +) +from .search_service import ( + ExperimentInfo, + SearchRequest, + SearchResponse, +) +from .serving_config import ( + ServingConfig, +) +from .serving_config_service import ( + AddControlRequest, + CreateServingConfigRequest, + DeleteServingConfigRequest, + GetServingConfigRequest, + ListServingConfigsRequest, + ListServingConfigsResponse, + RemoveControlRequest, + UpdateServingConfigRequest, +) +from .user_event import ( + CompletionDetail, + ProductDetail, + PurchaseTransaction, + UserEvent, +) +from .user_event_service import ( + CollectUserEventRequest, + RejoinUserEventsMetadata, + RejoinUserEventsRequest, + RejoinUserEventsResponse, + WriteUserEventRequest, +) + +__all__ = ( + 'AttributesConfig', + 'Catalog', + 'CatalogAttribute', + 'CompletionConfig', + 'MerchantCenterFeedFilter', + 'MerchantCenterLink', + 'MerchantCenterLinkingConfig', + 'ProductLevelConfig', + 'AddCatalogAttributeRequest', + 'BatchRemoveCatalogAttributesRequest', + 'BatchRemoveCatalogAttributesResponse', + 'GetAttributesConfigRequest', + 'GetCompletionConfigRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'RemoveCatalogAttributeRequest', + 'ReplaceCatalogAttributeRequest', + 'SetDefaultBranchRequest', + 'UpdateAttributesConfigRequest', + 'UpdateCatalogRequest', + 'UpdateCompletionConfigRequest', + 'Audience', + 'ColorInfo', + 'Condition', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'LocalInventory', + 'PriceInfo', + 'Rating', + 'Rule', + 'UserInfo', + 'AttributeConfigLevel', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'SolutionType', + 'CompleteQueryRequest', + 'CompleteQueryResponse', + 'Control', + 'CreateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + 'UpdateControlRequest', + 'BigQueryOutputResult', + 'ExportErrorsConfig', + 'ExportMetadata', + 'ExportProductsResponse', + 'ExportUserEventsResponse', + 'GcsOutputResult', + 'OutputResult', + 'BigQuerySource', + 'CompletionDataInputConfig', + 'GcsSource', + 'ImportCompletionDataRequest', + 'ImportCompletionDataResponse', + 'ImportErrorsConfig', + 'ImportMetadata', + 'ImportProductsRequest', + 'ImportProductsResponse', + 'ImportUserEventsRequest', + 'ImportUserEventsResponse', + 'ProductInlineSource', + 'ProductInputConfig', + 'UserEventImportSummary', + 'UserEventInlineSource', + 'UserEventInputConfig', + 'Model', + 'CreateModelMetadata', + 'CreateModelRequest', + 'DeleteModelRequest', + 'GetModelRequest', + 'ListModelsRequest', + 'ListModelsResponse', + 'PauseModelRequest', + 'ResumeModelRequest', + 'TuneModelMetadata', + 'TuneModelRequest', + 'TuneModelResponse', + 'UpdateModelRequest', + 'PredictRequest', + 'PredictResponse', + 'Product', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesResponse', + 'CreateProductRequest', + 'DeleteProductRequest', + 'GetProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesResponse', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesResponse', + 'SetInventoryMetadata', + 'SetInventoryRequest', + 'SetInventoryResponse', + 'UpdateProductRequest', + 'Promotion', + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + 'ExperimentInfo', + 'SearchRequest', + 'SearchResponse', + 'ServingConfig', + 'AddControlRequest', + 'CreateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'RemoveControlRequest', + 'UpdateServingConfigRequest', + 'CompletionDetail', + 'ProductDetail', + 'PurchaseTransaction', + 'UserEvent', + 'CollectUserEventRequest', + 'RejoinUserEventsMetadata', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'WriteUserEventRequest', +) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog.py new file mode 100644 index 00000000..6fdb0453 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog.py @@ -0,0 +1,689 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'ProductLevelConfig', + 'CatalogAttribute', + 'AttributesConfig', + 'CompletionConfig', + 'MerchantCenterLink', + 'MerchantCenterFeedFilter', + 'MerchantCenterLinkingConfig', + 'Catalog', + }, +) + + +class ProductLevelConfig(proto.Message): + r"""Configures what level the product should be uploaded with + regards to how users will be send events and how predictions + will be made. + + Attributes: + ingestion_product_type (str): + The type of [Product][google.cloud.retail.v2beta.Product]s + allowed to be ingested into the catalog. Acceptable values + are: + + - ``primary`` (default): You can ingest + [Product][google.cloud.retail.v2beta.Product]s of all + types. When ingesting a + [Product][google.cloud.retail.v2beta.Product], its type + will default to + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + if unset. + - ``variant`` (incompatible with Retail Search): You can + only ingest + [Product.Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s. This + means + [Product.primary_product_id][google.cloud.retail.v2beta.Product.primary_product_id] + cannot be empty. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``variant`` and + [merchant_center_product_id_field][google.cloud.retail.v2beta.ProductLevelConfig.merchant_center_product_id_field] + is ``itemGroupId``, an INVALID_ARGUMENT error is returned. + + See `Product + levels `__ + for more details. + merchant_center_product_id_field (str): + Which field of `Merchant Center + Product `__ + should be imported as + [Product.id][google.cloud.retail.v2beta.Product.id]. + Acceptable values are: + + - ``offerId`` (default): Import ``offerId`` as the product + ID. + - ``itemGroupId``: Import ``itemGroupId`` as the product + ID. Notice that Retail API will choose one item from the + ones with the same ``itemGroupId``, and use it to + represent the item group. + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + If this field is ``itemGroupId`` and + [ingestion_product_type][google.cloud.retail.v2beta.ProductLevelConfig.ingestion_product_type] + is ``variant``, an INVALID_ARGUMENT error is returned. + + See `Product + levels `__ + for more details. + """ + + ingestion_product_type: str = proto.Field( + proto.STRING, + number=1, + ) + merchant_center_product_id_field: str = proto.Field( + proto.STRING, + number=2, + ) + + +class CatalogAttribute(proto.Message): + r"""Catalog level attribute config for an attribute. For example, + if customers want to enable/disable facet for a specific + attribute. + + Attributes: + key (str): + Required. Attribute name. For example: ``color``, + ``brands``, ``attributes.custom_attribute``, such as + ``attributes.xyz``. To be indexable, the attribute name can + contain only alpha-numeric characters and underscores. For + example, an attribute named ``attributes.abc_xyz`` can be + indexed, but an attribute named ``attributes.abc-xyz`` + cannot be indexed. + + If the attribute key starts with ``attributes.``, then the + attribute is a custom attribute. Attributes such as + ``brands``, ``patterns``, and ``title`` are built-in and + called system attributes. + in_use (bool): + Output only. Indicates whether this attribute has been used + by any products. ``True`` if at least one + [Product][google.cloud.retail.v2beta.Product] is using this + attribute in + [Product.attributes][google.cloud.retail.v2beta.Product.attributes]. + Otherwise, this field is ``False``. + + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + can be pre-loaded by using + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute], + [CatalogService.ImportCatalogAttributes][], or + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig] + APIs. This field is ``False`` for pre-loaded + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s. + + Only pre-loaded [catalog + attributes][google.cloud.retail.v2beta.CatalogAttribute] + that are neither in use by products nor predefined can be + deleted. [Catalog + attributes][google.cloud.retail.v2beta.CatalogAttribute] + that are either in use by products or are predefined + attributes cannot be deleted; however, their configuration + properties will reset to default values upon removal + request. + + After catalog changes, it takes about 10 minutes for this + field to update. + type_ (google.cloud.retail_v2beta.types.CatalogAttribute.AttributeType): + Output only. The type of this attribute. This is derived + from the attribute in + [Product.attributes][google.cloud.retail.v2beta.Product.attributes]. + indexable_option (google.cloud.retail_v2beta.types.CatalogAttribute.IndexableOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2beta.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if INDEXABLE_ENABLED + attribute values are indexed so that it can be filtered, + faceted, or boosted in + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search]. + + Must be specified, otherwise throws INVALID_FORMAT error. + dynamic_facetable_option (google.cloud.retail_v2beta.types.CatalogAttribute.DynamicFacetableOption): + If DYNAMIC_FACETABLE_ENABLED, attribute values are available + for dynamic facet. Could only be DYNAMIC_FACETABLE_DISABLED + if + [CatalogAttribute.indexable_option][google.cloud.retail.v2beta.CatalogAttribute.indexable_option] + is INDEXABLE_DISABLED. Otherwise, an INVALID_ARGUMENT error + is returned. + + Must be specified, otherwise throws INVALID_FORMAT error. + searchable_option (google.cloud.retail_v2beta.types.CatalogAttribute.SearchableOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2beta.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if SEARCHABLE_ENABLED, + attribute values are searchable by text queries in + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search]. + + If SEARCHABLE_ENABLED but attribute type is numerical, + attribute values will not be searchable by text queries in + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search], + as there are no text values associated to numerical + attributes. + + Must be specified, otherwise throws INVALID_FORMAT error. + recommendations_filtering_option (google.cloud.retail_v2beta.types.RecommendationsFilteringOption): + When + [AttributesConfig.attribute_config_level][google.cloud.retail.v2beta.AttributesConfig.attribute_config_level] + is CATALOG_LEVEL_ATTRIBUTE_CONFIG, if + RECOMMENDATIONS_FILTERING_ENABLED, attribute values are + filterable for recommendations. This option works for + categorical features only, does not work for numerical + features, inventory filtering. + exact_searchable_option (google.cloud.retail_v2beta.types.CatalogAttribute.ExactSearchableOption): + If EXACT_SEARCHABLE_ENABLED, attribute values will be exact + searchable. This property only applies to textual custom + attributes and requires indexable set to enabled to enable + exact-searchable. If unset, the server behavior defaults to + [EXACT_SEARCHABLE_DISABLED][google.cloud.retail.v2beta.CatalogAttribute.ExactSearchableOption.EXACT_SEARCHABLE_DISABLED]. + retrievable_option (google.cloud.retail_v2beta.types.CatalogAttribute.RetrievableOption): + If RETRIEVABLE_ENABLED, attribute values are retrievable in + the search results. If unset, the server behavior defaults + to + [RETRIEVABLE_DISABLED][google.cloud.retail.v2beta.CatalogAttribute.RetrievableOption.RETRIEVABLE_DISABLED]. + """ + class AttributeType(proto.Enum): + r"""The type of an attribute. + + Values: + UNKNOWN (0): + The type of the attribute is unknown. + + Used when type cannot be derived from attribute that is not + [in_use][google.cloud.retail.v2beta.CatalogAttribute.in_use]. + TEXTUAL (1): + Textual attribute. + NUMERICAL (2): + Numerical attribute. + """ + UNKNOWN = 0 + TEXTUAL = 1 + NUMERICAL = 2 + + class IndexableOption(proto.Enum): + r"""The status of the indexable option of a catalog attribute. + + Values: + INDEXABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + INDEXABLE_ENABLED (1): + Indexable option enabled for an attribute. + INDEXABLE_DISABLED (2): + Indexable option disabled for an attribute. + """ + INDEXABLE_OPTION_UNSPECIFIED = 0 + INDEXABLE_ENABLED = 1 + INDEXABLE_DISABLED = 2 + + class DynamicFacetableOption(proto.Enum): + r"""The status of the dynamic facetable option of a catalog + attribute. + + Values: + DYNAMIC_FACETABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + DYNAMIC_FACETABLE_ENABLED (1): + Dynamic facetable option enabled for an + attribute. + DYNAMIC_FACETABLE_DISABLED (2): + Dynamic facetable option disabled for an + attribute. + """ + DYNAMIC_FACETABLE_OPTION_UNSPECIFIED = 0 + DYNAMIC_FACETABLE_ENABLED = 1 + DYNAMIC_FACETABLE_DISABLED = 2 + + class SearchableOption(proto.Enum): + r"""The status of the searchable option of a catalog attribute. + + Values: + SEARCHABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + SEARCHABLE_ENABLED (1): + Searchable option enabled for an attribute. + SEARCHABLE_DISABLED (2): + Searchable option disabled for an attribute. + """ + SEARCHABLE_OPTION_UNSPECIFIED = 0 + SEARCHABLE_ENABLED = 1 + SEARCHABLE_DISABLED = 2 + + class ExactSearchableOption(proto.Enum): + r"""The status of the exact-searchable option of a catalog + attribute. + + Values: + EXACT_SEARCHABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + EXACT_SEARCHABLE_ENABLED (1): + Exact searchable option enabled for an + attribute. + EXACT_SEARCHABLE_DISABLED (2): + Exact searchable option disabled for an + attribute. + """ + EXACT_SEARCHABLE_OPTION_UNSPECIFIED = 0 + EXACT_SEARCHABLE_ENABLED = 1 + EXACT_SEARCHABLE_DISABLED = 2 + + class RetrievableOption(proto.Enum): + r"""The status of the retrievable option of a catalog attribute. + + Values: + RETRIEVABLE_OPTION_UNSPECIFIED (0): + Value used when unset. + RETRIEVABLE_ENABLED (1): + Retrievable option enabled for an attribute. + RETRIEVABLE_DISABLED (2): + Retrievable option disabled for an attribute. + """ + RETRIEVABLE_OPTION_UNSPECIFIED = 0 + RETRIEVABLE_ENABLED = 1 + RETRIEVABLE_DISABLED = 2 + + key: str = proto.Field( + proto.STRING, + number=1, + ) + in_use: bool = proto.Field( + proto.BOOL, + number=9, + ) + type_: AttributeType = proto.Field( + proto.ENUM, + number=10, + enum=AttributeType, + ) + indexable_option: IndexableOption = proto.Field( + proto.ENUM, + number=5, + enum=IndexableOption, + ) + dynamic_facetable_option: DynamicFacetableOption = proto.Field( + proto.ENUM, + number=6, + enum=DynamicFacetableOption, + ) + searchable_option: SearchableOption = proto.Field( + proto.ENUM, + number=7, + enum=SearchableOption, + ) + recommendations_filtering_option: common.RecommendationsFilteringOption = proto.Field( + proto.ENUM, + number=8, + enum=common.RecommendationsFilteringOption, + ) + exact_searchable_option: ExactSearchableOption = proto.Field( + proto.ENUM, + number=11, + enum=ExactSearchableOption, + ) + retrievable_option: RetrievableOption = proto.Field( + proto.ENUM, + number=12, + enum=RetrievableOption, + ) + + +class AttributesConfig(proto.Message): + r"""Catalog level attribute config. + + Attributes: + name (str): + Required. Immutable. The fully qualified resource name of + the attribute config. Format: + ``projects/*/locations/*/catalogs/*/attributesConfig`` + catalog_attributes (MutableMapping[str, google.cloud.retail_v2beta.types.CatalogAttribute]): + Enable attribute(s) config at catalog level. For example, + indexable, dynamic_facetable, or searchable for each + attribute. + + The key is catalog attribute's name. For example: ``color``, + ``brands``, ``attributes.custom_attribute``, such as + ``attributes.xyz``. + + The maximum number of catalog attributes allowed in a + request is 1000. + attribute_config_level (google.cloud.retail_v2beta.types.AttributeConfigLevel): + Output only. The + [AttributeConfigLevel][google.cloud.retail.v2beta.AttributeConfigLevel] + used for this catalog. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attributes: MutableMapping[str, 'CatalogAttribute'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message='CatalogAttribute', + ) + attribute_config_level: common.AttributeConfigLevel = proto.Field( + proto.ENUM, + number=3, + enum=common.AttributeConfigLevel, + ) + + +class CompletionConfig(proto.Message): + r"""Catalog level autocomplete config for customers to customize + autocomplete feature's settings. + + Attributes: + name (str): + Required. Immutable. Fully qualified name + ``projects/*/locations/*/catalogs/*/completionConfig`` + matching_order (str): + Specifies the matching order for autocomplete suggestions, + e.g., a query consisting of 'sh' with 'out-of-order' + specified would suggest "women's shoes", whereas a query of + 'red s' with 'exact-prefix' specified would suggest "red + shoes". Currently supported values: + + - 'out-of-order' + - 'exact-prefix' + + Default value: 'exact-prefix'. + max_suggestions (int): + The maximum number of autocomplete + suggestions returned per term. Default value is + 20. If left unset or set to 0, then will + fallback to default value. + + Value range is 1 to 20. + min_prefix_length (int): + The minimum number of characters needed to be + typed in order to get suggestions. Default value + is 2. If left unset or set to 0, then will + fallback to default value. + + Value range is 1 to 20. + auto_learning (bool): + If set to true, the auto learning function is enabled. Auto + learning uses user data to generate suggestions using ML + techniques. Default value is false. Only after enabling auto + learning can users use ``cloud-retail`` data in + [CompleteQueryRequest][google.cloud.retail.v2beta.CompleteQueryRequest]. + suggestions_input_config (google.cloud.retail_v2beta.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete suggestion phrases. + last_suggestions_import_operation (str): + Output only. Name of the LRO corresponding to the latest + suggestion terms list import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + denylist_input_config (google.cloud.retail_v2beta.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete denylist phrases. + last_denylist_import_operation (str): + Output only. Name of the LRO corresponding to the latest + denylist import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + allowlist_input_config (google.cloud.retail_v2beta.types.CompletionDataInputConfig): + Output only. The source data for the latest + import of the autocomplete allowlist phrases. + last_allowlist_import_operation (str): + Output only. Name of the LRO corresponding to the latest + allowlist import. + + Can use + [GetOperation][google.longrunning.Operations.GetOperation] + API to retrieve the latest state of the Long Running + Operation. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + matching_order: str = proto.Field( + proto.STRING, + number=2, + ) + max_suggestions: int = proto.Field( + proto.INT32, + number=3, + ) + min_prefix_length: int = proto.Field( + proto.INT32, + number=4, + ) + auto_learning: bool = proto.Field( + proto.BOOL, + number=11, + ) + suggestions_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=5, + message=import_config.CompletionDataInputConfig, + ) + last_suggestions_import_operation: str = proto.Field( + proto.STRING, + number=6, + ) + denylist_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=7, + message=import_config.CompletionDataInputConfig, + ) + last_denylist_import_operation: str = proto.Field( + proto.STRING, + number=8, + ) + allowlist_input_config: import_config.CompletionDataInputConfig = proto.Field( + proto.MESSAGE, + number=9, + message=import_config.CompletionDataInputConfig, + ) + last_allowlist_import_operation: str = proto.Field( + proto.STRING, + number=10, + ) + + +class MerchantCenterLink(proto.Message): + r"""Represents a link between a Merchant Center account and a + branch. Once a link is established, products from the linked + merchant center account will be streamed to the linked branch. + + Attributes: + merchant_center_account_id (int): + Required. The linked `Merchant center account + ID `__. + The account must be a standalone account or a sub-account of + a MCA. + branch_id (str): + The branch ID (e.g. 0/1/2) within this catalog that products + from merchant_center_account_id are streamed to. When + updating this field, an empty value will use the currently + configured default branch. However, changing the default + branch later on won't change the linked branch here. + + A single branch ID can only have one linked merchant center + account ID. + destinations (MutableSequence[str]): + String representing the destination to import for, all if + left empty. List of possible values is given in `Included + destination `__. + List of allowed string values: "Shopping_ads", + "Buy_on_google_listings", "Display_ads", "Local_inventory + \_ads", "Free_listings", "Free_local_listings" NOTE: The + string values are case sensitive. + region_code (str): + Region code of offers to accept. 2-letter Uppercase ISO + 3166-1 alpha-2 code. List of values can be found + `here `__ + under the ``region`` tag. If left blank no region filtering + will be performed. + + Example value: ``US``. + language_code (str): + Language of the title/description and other string + attributes. Use language tags defined by `BCP + 47 `__. ISO + 639-1. + + This specifies the language of offers in Merchant Center + that will be accepted. If empty no language filtering will + be performed. + + Example value: ``en``. + feeds (MutableSequence[google.cloud.retail_v2beta.types.MerchantCenterFeedFilter]): + Criteria for the Merchant Center feeds to be + ingested via the link. All offers will be + ingested if the list is empty. Otherwise the + offers will be ingested from selected feeds. + """ + + merchant_center_account_id: int = proto.Field( + proto.INT64, + number=1, + ) + branch_id: str = proto.Field( + proto.STRING, + number=2, + ) + destinations: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + region_code: str = proto.Field( + proto.STRING, + number=4, + ) + language_code: str = proto.Field( + proto.STRING, + number=5, + ) + feeds: MutableSequence['MerchantCenterFeedFilter'] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message='MerchantCenterFeedFilter', + ) + + +class MerchantCenterFeedFilter(proto.Message): + r"""Merchant Center Feed filter criterion. + + Attributes: + primary_feed_id (int): + Merchant Center primary feed ID. + primary_feed_name (str): + Merchant Center primary feed name. The name + is used for the display purposes only. + """ + + primary_feed_id: int = proto.Field( + proto.INT64, + number=1, + ) + primary_feed_name: str = proto.Field( + proto.STRING, + number=2, + ) + + +class MerchantCenterLinkingConfig(proto.Message): + r"""Configures Merchant Center linking. + Links contained in the config will be used to sync data from a + Merchant Center account to a Cloud Retail branch. + + Attributes: + links (MutableSequence[google.cloud.retail_v2beta.types.MerchantCenterLink]): + Links between Merchant Center accounts and + branches. + """ + + links: MutableSequence['MerchantCenterLink'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='MerchantCenterLink', + ) + + +class Catalog(proto.Message): + r"""The catalog configuration. + + Attributes: + name (str): + Required. Immutable. The fully qualified + resource name of the catalog. + display_name (str): + Required. Immutable. The catalog display name. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + product_level_config (google.cloud.retail_v2beta.types.ProductLevelConfig): + Required. The product level configuration. + merchant_center_linking_config (google.cloud.retail_v2beta.types.MerchantCenterLinkingConfig): + The Merchant Center linking configuration. + Once a link is added, the data stream from + Merchant Center to Cloud Retail will be enabled + automatically. The requester must have access to + the merchant center account in order to make + changes to this field. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + product_level_config: 'ProductLevelConfig' = proto.Field( + proto.MESSAGE, + number=4, + message='ProductLevelConfig', + ) + merchant_center_linking_config: 'MerchantCenterLinkingConfig' = proto.Field( + proto.MESSAGE, + number=6, + message='MerchantCenterLinkingConfig', + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog_service.py new file mode 100644 index 00000000..0155f8a1 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/catalog_service.py @@ -0,0 +1,518 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import catalog as gcr_catalog +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'ListCatalogsRequest', + 'ListCatalogsResponse', + 'UpdateCatalogRequest', + 'SetDefaultBranchRequest', + 'GetDefaultBranchRequest', + 'GetDefaultBranchResponse', + 'GetCompletionConfigRequest', + 'UpdateCompletionConfigRequest', + 'GetAttributesConfigRequest', + 'UpdateAttributesConfigRequest', + 'AddCatalogAttributeRequest', + 'RemoveCatalogAttributeRequest', + 'BatchRemoveCatalogAttributesRequest', + 'BatchRemoveCatalogAttributesResponse', + 'ReplaceCatalogAttributeRequest', + }, +) + + +class ListCatalogsRequest(proto.Message): + r"""Request for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + method. + + Attributes: + parent (str): + Required. The account resource name with an associated + location. + + If the caller does not have permission to list + [Catalog][google.cloud.retail.v2beta.Catalog]s under this + location, regardless of whether or not this location exists, + a PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of + [Catalog][google.cloud.retail.v2beta.Catalog]s to return. If + unspecified, defaults to 50. The maximum allowed value is + 1000. Values above 1000 will be coerced to 1000. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [ListCatalogsResponse.next_page_token][google.cloud.retail.v2beta.ListCatalogsResponse.next_page_token], + received from a previous + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + """ + + 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 ListCatalogsResponse(proto.Message): + r"""Response for + [CatalogService.ListCatalogs][google.cloud.retail.v2beta.CatalogService.ListCatalogs] + method. + + Attributes: + catalogs (MutableSequence[google.cloud.retail_v2beta.types.Catalog]): + All the customer's + [Catalog][google.cloud.retail.v2beta.Catalog]s. + next_page_token (str): + A token that can be sent as + [ListCatalogsRequest.page_token][google.cloud.retail.v2beta.ListCatalogsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + catalogs: MutableSequence[gcr_catalog.Catalog] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class UpdateCatalogRequest(proto.Message): + r"""Request for + [CatalogService.UpdateCatalog][google.cloud.retail.v2beta.CatalogService.UpdateCatalog] + method. + + Attributes: + catalog (google.cloud.retail_v2beta.types.Catalog): + Required. The [Catalog][google.cloud.retail.v2beta.Catalog] + to update. + + If the caller does not have permission to update the + [Catalog][google.cloud.retail.v2beta.Catalog], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Catalog][google.cloud.retail.v2beta.Catalog] to + update does not exist, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Catalog][google.cloud.retail.v2beta.Catalog] to update. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + """ + + catalog: gcr_catalog.Catalog = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.Catalog, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class SetDefaultBranchRequest(proto.Message): + r"""Request message to set a specified branch as new default_branch. + + Attributes: + catalog (str): + Full resource name of the catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + branch_id (str): + The final component of the resource name of a branch. + + This field must be one of "0", "1" or "2". Otherwise, an + INVALID_ARGUMENT error is returned. + + If there are no sufficient active products in the targeted + branch and + [force][google.cloud.retail.v2beta.SetDefaultBranchRequest.force] + is not set, a FAILED_PRECONDITION error is returned. + note (str): + Some note on this request, this can be retrieved by + [CatalogService.GetDefaultBranch][google.cloud.retail.v2beta.CatalogService.GetDefaultBranch] + before next valid default branch set occurs. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + force (bool): + If set to true, it permits switching to a branch with + [branch_id][google.cloud.retail.v2beta.SetDefaultBranchRequest.branch_id] + even if it has no sufficient active products. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + branch_id: str = proto.Field( + proto.STRING, + number=2, + ) + note: str = proto.Field( + proto.STRING, + number=3, + ) + force: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class GetDefaultBranchRequest(proto.Message): + r"""Request message to show which branch is currently the default + branch. + + Attributes: + catalog (str): + The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog``. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetDefaultBranchResponse(proto.Message): + r"""Response message of + [CatalogService.GetDefaultBranch][google.cloud.retail.v2beta.CatalogService.GetDefaultBranch]. + + Attributes: + branch (str): + Full resource name of the branch id currently + set as default branch. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when this branch is set to default. + note (str): + This corresponds to + [SetDefaultBranchRequest.note][google.cloud.retail.v2beta.SetDefaultBranchRequest.note] + field, when this branch was set as default. + """ + + branch: str = proto.Field( + proto.STRING, + number=1, + ) + set_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + note: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetCompletionConfigRequest(proto.Message): + r"""Request for + [CatalogService.GetCompletionConfig][google.cloud.retail.v2beta.CatalogService.GetCompletionConfig] + method. + + Attributes: + name (str): + Required. Full CompletionConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/completionConfig`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateCompletionConfigRequest(proto.Message): + r"""Request for + [CatalogService.UpdateCompletionConfig][google.cloud.retail.v2beta.CatalogService.UpdateCompletionConfig] + method. + + Attributes: + completion_config (google.cloud.retail_v2beta.types.CompletionConfig): + Required. The + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update. + + If the caller does not have permission to update the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig], + then a PERMISSION_DENIED error is returned. + + If the + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update does not exist, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CompletionConfig][google.cloud.retail.v2beta.CompletionConfig] + to update. The following are the only supported fields: + + - [CompletionConfig.matching_order][google.cloud.retail.v2beta.CompletionConfig.matching_order] + - [CompletionConfig.max_suggestions][google.cloud.retail.v2beta.CompletionConfig.max_suggestions] + - [CompletionConfig.min_prefix_length][google.cloud.retail.v2beta.CompletionConfig.min_prefix_length] + - [CompletionConfig.auto_learning][google.cloud.retail.v2beta.CompletionConfig.auto_learning] + + If not set, all supported fields are updated. + """ + + completion_config: gcr_catalog.CompletionConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.CompletionConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetAttributesConfigRequest(proto.Message): + r"""Request for + [CatalogService.GetAttributesConfig][google.cloud.retail.v2beta.CatalogService.GetAttributesConfig] + method. + + Attributes: + name (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateAttributesConfigRequest(proto.Message): + r"""Request for + [CatalogService.UpdateAttributesConfig][google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig] + method. + + Attributes: + attributes_config (google.cloud.retail_v2beta.types.AttributesConfig): + Required. The + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [AttributesConfig][google.cloud.retail.v2beta.AttributesConfig] + to update. The following is the only supported field: + + - [AttributesConfig.catalog_attributes][google.cloud.retail.v2beta.AttributesConfig.catalog_attributes] + + If not set, all supported fields are updated. + """ + + attributes_config: gcr_catalog.AttributesConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_catalog.AttributesConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class AddCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.AddCatalogAttribute][google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + catalog_attribute (google.cloud.retail_v2beta.types.CatalogAttribute): + Required. The + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to add. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attribute: gcr_catalog.CatalogAttribute = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_catalog.CatalogAttribute, + ) + + +class RemoveCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.RemoveCatalogAttribute][google.cloud.retail.v2beta.CatalogService.RemoveCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + key (str): + Required. The attribute name key of the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to remove. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + key: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BatchRemoveCatalogAttributesRequest(proto.Message): + r"""Request for + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes] + method. + + Attributes: + attributes_config (str): + Required. The attributes config resource shared by all + catalog attributes being deleted. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + attribute_keys (MutableSequence[str]): + Required. The attribute name keys of the + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]s + to delete. A maximum of 1000 catalog attributes can be + deleted in a batch. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + attribute_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class BatchRemoveCatalogAttributesResponse(proto.Message): + r"""Response of the + [CatalogService.BatchRemoveCatalogAttributes][google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes]. + + Attributes: + deleted_catalog_attributes (MutableSequence[str]): + Catalog attributes that were deleted. Only pre-loaded + [catalog + attributes][google.cloud.retail.v2beta.CatalogAttribute] + that are neither [in + use][google.cloud.retail.v2beta.CatalogAttribute.in_use] by + products nor predefined can be deleted. + reset_catalog_attributes (MutableSequence[str]): + Catalog attributes that were reset. [Catalog + attributes][google.cloud.retail.v2beta.CatalogAttribute] + that are either [in + use][google.cloud.retail.v2beta.CatalogAttribute.in_use] by + products or are predefined attributes cannot be deleted; + however, their configuration properties will reset to + default values upon removal request. + """ + + deleted_catalog_attributes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + reset_catalog_attributes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class ReplaceCatalogAttributeRequest(proto.Message): + r"""Request for + [CatalogService.ReplaceCatalogAttribute][google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute] + method. + + Attributes: + attributes_config (str): + Required. Full AttributesConfig resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/attributesConfig`` + catalog_attribute (google.cloud.retail_v2beta.types.CatalogAttribute): + Required. The updated + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute]. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + to update. The following are NOT supported: + + - [CatalogAttribute.key][google.cloud.retail.v2beta.CatalogAttribute.key] + + If not set, all supported fields are updated. + """ + + attributes_config: str = proto.Field( + proto.STRING, + number=1, + ) + catalog_attribute: gcr_catalog.CatalogAttribute = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_catalog.CatalogAttribute, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=3, + message=field_mask_pb2.FieldMask, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/common.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/common.py new file mode 100644 index 00000000..571d623e --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/common.py @@ -0,0 +1,1259 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'AttributeConfigLevel', + 'SolutionType', + 'RecommendationsFilteringOption', + 'SearchSolutionUseCase', + 'Condition', + 'Rule', + 'Audience', + 'ColorInfo', + 'CustomAttribute', + 'FulfillmentInfo', + 'Image', + 'Interval', + 'PriceInfo', + 'Rating', + 'UserInfo', + 'LocalInventory', + }, +) + + +class AttributeConfigLevel(proto.Enum): + r"""At which level we offer configuration for attributes. + + Values: + ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED (0): + Value used when unset. In this case, server behavior + defaults to + [CATALOG_LEVEL_ATTRIBUTE_CONFIG][google.cloud.retail.v2beta.AttributeConfigLevel.CATALOG_LEVEL_ATTRIBUTE_CONFIG]. + PRODUCT_LEVEL_ATTRIBUTE_CONFIG (1): + At this level, we honor the attribute configurations set in + [Product.attributes][google.cloud.retail.v2beta.Product.attributes]. + CATALOG_LEVEL_ATTRIBUTE_CONFIG (2): + At this level, we honor the attribute configurations set in + [CatalogConfig.attribute_configs][]. + """ + ATTRIBUTE_CONFIG_LEVEL_UNSPECIFIED = 0 + PRODUCT_LEVEL_ATTRIBUTE_CONFIG = 1 + CATALOG_LEVEL_ATTRIBUTE_CONFIG = 2 + + +class SolutionType(proto.Enum): + r"""The type of solution. + + Values: + SOLUTION_TYPE_UNSPECIFIED (0): + Default value. + SOLUTION_TYPE_RECOMMENDATION (1): + Used for Recommendations AI. + SOLUTION_TYPE_SEARCH (2): + Used for Retail Search. + """ + SOLUTION_TYPE_UNSPECIFIED = 0 + SOLUTION_TYPE_RECOMMENDATION = 1 + SOLUTION_TYPE_SEARCH = 2 + + +class RecommendationsFilteringOption(proto.Enum): + r"""If filtering for recommendations is enabled. + + Values: + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED (0): + Value used when unset. In this case, server behavior + defaults to + [RECOMMENDATIONS_FILTERING_DISABLED][google.cloud.retail.v2beta.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED]. + RECOMMENDATIONS_FILTERING_DISABLED (1): + Recommendation filtering is disabled. + RECOMMENDATIONS_FILTERING_ENABLED (3): + Recommendation filtering is enabled. + """ + RECOMMENDATIONS_FILTERING_OPTION_UNSPECIFIED = 0 + RECOMMENDATIONS_FILTERING_DISABLED = 1 + RECOMMENDATIONS_FILTERING_ENABLED = 3 + + +class SearchSolutionUseCase(proto.Enum): + r"""The use case of Cloud Retail Search. + + Values: + SEARCH_SOLUTION_USE_CASE_UNSPECIFIED (0): + The value when it's unspecified. In this case, server + behavior defaults to + [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2beta.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH]. + SEARCH_SOLUTION_USE_CASE_SEARCH (1): + Search use case. Expects the traffic has a non-empty + [query][google.cloud.retail.v2beta.SearchRequest.query]. + SEARCH_SOLUTION_USE_CASE_BROWSE (2): + Browse use case. Expects the traffic has an empty + [query][google.cloud.retail.v2beta.SearchRequest.query]. + """ + SEARCH_SOLUTION_USE_CASE_UNSPECIFIED = 0 + SEARCH_SOLUTION_USE_CASE_SEARCH = 1 + SEARCH_SOLUTION_USE_CASE_BROWSE = 2 + + +class Condition(proto.Message): + r"""Metadata that is used to define a condition that triggers an action. + A valid condition must specify at least one of 'query_terms' or + 'products_filter'. If multiple fields are specified, the condition + is met if all the fields are satisfied e.g. if a set of query terms + and product_filter are set, then only items matching the + product_filter for requests with a query matching the query terms + wil get boosted. + + Attributes: + query_terms (MutableSequence[google.cloud.retail_v2beta.types.Condition.QueryTerm]): + A list (up to 10 entries) of terms to match + the query on. If not specified, match all + queries. If many query terms are specified, the + condition is matched if any of the terms is a + match (i.e. using the OR operator). + active_time_range (MutableSequence[google.cloud.retail_v2beta.types.Condition.TimeRange]): + Range of time(s) specifying when Condition is + active. Condition true if any time range + matches. + """ + + class QueryTerm(proto.Message): + r"""Query terms that we want to match on. + + Attributes: + value (str): + The value of the term to match on. + Value cannot be empty. + Value can have at most 3 terms if specified as a + partial match. Each space separated string is + considered as one term. For example, "a b c" is + 3 terms and allowed, but " a b c d" is 4 terms + and not allowed for a partial match. + full_match (bool): + Whether this is supposed to be a full or + partial match. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + ) + full_match: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class TimeRange(proto.Message): + r"""Used for time-dependent conditions. + Example: Want to have rule applied for week long sale. + + Attributes: + start_time (google.protobuf.timestamp_pb2.Timestamp): + Start of time range. Range is inclusive. + end_time (google.protobuf.timestamp_pb2.Timestamp): + End of time range. Range is inclusive. + """ + + start_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + end_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + query_terms: MutableSequence[QueryTerm] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=QueryTerm, + ) + active_time_range: MutableSequence[TimeRange] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=TimeRange, + ) + + +class Rule(proto.Message): + r"""A rule is a condition-action pair + + - A condition defines when a rule is to be triggered. + - An action specifies what occurs on that trigger. Currently rules + only work for [controls][google.cloud.retail.v2beta.Control] with + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2beta.SolutionType.SOLUTION_TYPE_SEARCH]. + + 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: + boost_action (google.cloud.retail_v2beta.types.Rule.BoostAction): + A boost action. + + This field is a member of `oneof`_ ``action``. + redirect_action (google.cloud.retail_v2beta.types.Rule.RedirectAction): + Redirects a shopper to a specific page. + + This field is a member of `oneof`_ ``action``. + oneway_synonyms_action (google.cloud.retail_v2beta.types.Rule.OnewaySynonymsAction): + Treats specific term as a synonym with a + group of terms. Group of terms will not be + treated as synonyms with the specific term. + + This field is a member of `oneof`_ ``action``. + do_not_associate_action (google.cloud.retail_v2beta.types.Rule.DoNotAssociateAction): + Prevents term from being associated with + other terms. + + This field is a member of `oneof`_ ``action``. + replacement_action (google.cloud.retail_v2beta.types.Rule.ReplacementAction): + Replaces specific terms in the query. + + This field is a member of `oneof`_ ``action``. + ignore_action (google.cloud.retail_v2beta.types.Rule.IgnoreAction): + Ignores specific terms from query during + search. + + This field is a member of `oneof`_ ``action``. + filter_action (google.cloud.retail_v2beta.types.Rule.FilterAction): + Filters results. + + This field is a member of `oneof`_ ``action``. + twoway_synonyms_action (google.cloud.retail_v2beta.types.Rule.TwowaySynonymsAction): + Treats a set of terms as synonyms of one + another. + + This field is a member of `oneof`_ ``action``. + condition (google.cloud.retail_v2beta.types.Condition): + Required. The condition that triggers the + rule. If the condition is empty, the rule will + always apply. + """ + + class BoostAction(proto.Message): + r"""A boost action to apply to results matching condition + specified above. + + Attributes: + boost (float): + Strength of the condition boost, which must be in [-1, 1]. + Negative boost means demotion. Default is 0.0. + + Setting to 1.0 gives the item a big promotion. However, it + does not necessarily mean that the boosted item will be the + top result at all times, nor that other items will be + excluded. Results could still be shown even when none of + them matches the condition. And results that are + significantly more relevant to the search query can still + trump your heavily favored but irrelevant items. + + Setting to -1.0 gives the item a big demotion. However, + results that are deeply relevant might still be shown. The + item will have an upstream battle to get a fairly high + ranking, but it is not blocked out completely. + + Setting to 0.0 means no boost applied. The boosting + condition is ignored. + products_filter (str): + The filter can have a max size of 5000 characters. An + expression which specifies which products to apply an action + to. The syntax and supported fields are the same as a filter + expression. See + [SearchRequest.filter][google.cloud.retail.v2beta.SearchRequest.filter] + for detail syntax and limitations. + + Examples: + + - To boost products with product ID "product_1" or + "product_2", and color "Red" or "Blue": *(id: + ANY("product_1", "product_2"))* *AND* *(colorFamilies: + ANY("Red", "Blue"))* + """ + + boost: float = proto.Field( + proto.FLOAT, + number=1, + ) + products_filter: str = proto.Field( + proto.STRING, + number=2, + ) + + class FilterAction(proto.Message): + r"""- Rule Condition: + + - No + [Condition.query_terms][google.cloud.retail.v2beta.Condition.query_terms] + provided is a global match. + - 1 or more + [Condition.query_terms][google.cloud.retail.v2beta.Condition.query_terms] + provided are combined with OR operator. + + - Action Input: The request query and filter that are applied to + the retrieved products, in addition to any filters already + provided with the SearchRequest. The AND operator is used to + combine the query's existing filters with the filter rule(s). + NOTE: May result in 0 results when filters conflict. + - Action Result: Filters the returned objects to be ONLY those that + passed the filter. + + Attributes: + filter (str): + A filter to apply on the matching condition results. + Supported features: + + - [filter][google.cloud.retail.v2beta.Rule.FilterAction.filter] + must be set. + - Filter syntax is identical to + [SearchRequest.filter][google.cloud.retail.v2beta.SearchRequest.filter]. + See more details at the Retail Search `user + guide `__. + - To filter products with product ID "product_1" or + "product_2", and color "Red" or "Blue": *(id: + ANY("product_1", "product_2"))* *AND* *(colorFamilies: + ANY("Red", "Blue"))* + """ + + filter: str = proto.Field( + proto.STRING, + number=1, + ) + + class RedirectAction(proto.Message): + r"""Redirects a shopper to a specific page. + + - Rule Condition: + + - Must specify + [Condition.query_terms][google.cloud.retail.v2beta.Condition.query_terms]. + + - Action Input: Request Query + - Action Result: Redirects shopper to provided uri. + + Attributes: + redirect_uri (str): + URL must have length equal or less than 2000 + characters. + """ + + redirect_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + class TwowaySynonymsAction(proto.Message): + r"""Creates a set of terms that will be treated as synonyms of each + other. Example: synonyms of "sneakers" and "shoes": + + - "sneakers" will use a synonym of "shoes". + - "shoes" will use a synonym of "sneakers". + + Attributes: + synonyms (MutableSequence[str]): + Defines a set of synonyms. + Can specify up to 100 synonyms. + Must specify at least 2 synonyms. + """ + + synonyms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class OnewaySynonymsAction(proto.Message): + r"""Maps a set of terms to a set of synonyms. Set of synonyms will be + treated as synonyms of each query term only. ``query_terms`` will + not be treated as synonyms of each other. Example: "sneakers" will + use a synonym of "shoes". "shoes" will not use a synonym of + "sneakers". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. + Will treat synonyms as their synonyms. + Not themselves synonyms of the synonyms. + Can specify up to 100 terms. + synonyms (MutableSequence[str]): + Defines a set of synonyms. + Cannot contain duplicates. + Can specify up to 100 synonyms. + oneway_terms (MutableSequence[str]): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + synonyms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + oneway_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + class DoNotAssociateAction(proto.Message): + r"""Prevents ``query_term`` from being associated with specified terms + during search. Example: Don't associate "gShoe" and "cheap". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. Will not consider + do_not_associate_terms for search if in search query. Can + specify up to 100 terms. + do_not_associate_terms (MutableSequence[str]): + Cannot contain duplicates or the query term. + Can specify up to 100 terms. + terms (MutableSequence[str]): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + do_not_associate_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + class ReplacementAction(proto.Message): + r"""Replaces a term in the query. Multiple replacement candidates can be + specified. All ``query_terms`` will be replaced with the replacement + term. Example: Replace "gShoe" with "google shoe". + + Attributes: + query_terms (MutableSequence[str]): + Terms from the search query. + Will be replaced by replacement term. + Can specify up to 100 terms. + replacement_term (str): + Term that will be used for replacement. + term (str): + Will be [deprecated = true] post migration; + """ + + query_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + replacement_term: str = proto.Field( + proto.STRING, + number=3, + ) + term: str = proto.Field( + proto.STRING, + number=1, + ) + + class IgnoreAction(proto.Message): + r"""Prevents a term in the query from being used in search. + Example: Don't search for "shoddy". + + Attributes: + ignore_terms (MutableSequence[str]): + Terms to ignore in the search query. + """ + + ignore_terms: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + boost_action: BoostAction = proto.Field( + proto.MESSAGE, + number=2, + oneof='action', + message=BoostAction, + ) + redirect_action: RedirectAction = proto.Field( + proto.MESSAGE, + number=3, + oneof='action', + message=RedirectAction, + ) + oneway_synonyms_action: OnewaySynonymsAction = proto.Field( + proto.MESSAGE, + number=6, + oneof='action', + message=OnewaySynonymsAction, + ) + do_not_associate_action: DoNotAssociateAction = proto.Field( + proto.MESSAGE, + number=7, + oneof='action', + message=DoNotAssociateAction, + ) + replacement_action: ReplacementAction = proto.Field( + proto.MESSAGE, + number=8, + oneof='action', + message=ReplacementAction, + ) + ignore_action: IgnoreAction = proto.Field( + proto.MESSAGE, + number=9, + oneof='action', + message=IgnoreAction, + ) + filter_action: FilterAction = proto.Field( + proto.MESSAGE, + number=10, + oneof='action', + message=FilterAction, + ) + twoway_synonyms_action: TwowaySynonymsAction = proto.Field( + proto.MESSAGE, + number=11, + oneof='action', + message=TwowaySynonymsAction, + ) + condition: 'Condition' = proto.Field( + proto.MESSAGE, + number=1, + message='Condition', + ) + + +class Audience(proto.Message): + r"""An intended audience of the + [Product][google.cloud.retail.v2beta.Product] for whom it's sold. + + Attributes: + genders (MutableSequence[str]): + The genders of the audience. Strongly encouraged to use the + standard values: "male", "female", "unisex". + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `gender `__. + Schema.org property + `Product.audience.suggestedGender `__. + age_groups (MutableSequence[str]): + The age groups of the audience. Strongly encouraged to use + the standard values: "newborn" (up to 3 months old), + "infant" (3–12 months old), "toddler" (1–5 years old), + "kids" (5–13 years old), "adult" (typically teens or older). + + At most 5 values are allowed. Each value must be a UTF-8 + encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `age_group `__. + Schema.org property + `Product.audience.suggestedMinAge `__ + and + `Product.audience.suggestedMaxAge `__. + """ + + genders: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + age_groups: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class ColorInfo(proto.Message): + r"""The color information of a + [Product][google.cloud.retail.v2beta.Product]. + + Attributes: + color_families (MutableSequence[str]): + The standard color families. Strongly recommended to use the + following standard color groups: "Red", "Pink", "Orange", + "Yellow", "Purple", "Green", "Cyan", "Blue", "Brown", + "White", "Gray", "Black" and "Mixed". Normally it is + expected to have only 1 color family. May consider using + single "Mixed" instead of multiple values. + + A maximum of 5 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + colors (MutableSequence[str]): + The color display names, which may be different from + standard color family names, such as the color aliases used + in the website frontend. Normally it is expected to have + only 1 color. May consider using single "Mixed" instead of + multiple values. + + A maximum of 75 colors are allowed. Each value must be a + UTF-8 encoded string with a length limit of 128 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + """ + + color_families: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + colors: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class CustomAttribute(proto.Message): + r"""A custom attribute that is not explicitly modeled in + [Product][google.cloud.retail.v2beta.Product]. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + text (MutableSequence[str]): + The textual values of this custom attribute. For example, + ``["yellow", "green"]`` when the key is "color". + + Empty string is not allowed. Otherwise, an INVALID_ARGUMENT + error is returned. + + Exactly one of + [text][google.cloud.retail.v2beta.CustomAttribute.text] or + [numbers][google.cloud.retail.v2beta.CustomAttribute.numbers] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. + numbers (MutableSequence[float]): + The numerical values of this custom attribute. For example, + ``[2.3, 15.4]`` when the key is "lengths_cm". + + Exactly one of + [text][google.cloud.retail.v2beta.CustomAttribute.text] or + [numbers][google.cloud.retail.v2beta.CustomAttribute.numbers] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. + searchable (bool): + This field is normally ignored unless + [AttributesConfig.attribute_config_level][google.cloud.retail.v2beta.AttributesConfig.attribute_config_level] + of the [Catalog][google.cloud.retail.v2beta.Catalog] is set + to the deprecated 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For + information about product-level attribute configuration, see + `Configuration + modes `__. + If true, custom attribute values are searchable by text + queries in + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2beta.UserEvent]. + + Only set if type + [text][google.cloud.retail.v2beta.CustomAttribute.text] is + set. Otherwise, a INVALID_ARGUMENT error is returned. + + This field is a member of `oneof`_ ``_searchable``. + indexable (bool): + This field is normally ignored unless + [AttributesConfig.attribute_config_level][google.cloud.retail.v2beta.AttributesConfig.attribute_config_level] + of the [Catalog][google.cloud.retail.v2beta.Catalog] is set + to the deprecated 'PRODUCT_LEVEL_ATTRIBUTE_CONFIG' mode. For + information about product-level attribute configuration, see + `Configuration + modes `__. + If true, custom attribute values are indexed, so that they + can be filtered, faceted or boosted in + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search]. + + This field is ignored in a + [UserEvent][google.cloud.retail.v2beta.UserEvent]. + + See + [SearchRequest.filter][google.cloud.retail.v2beta.SearchRequest.filter], + [SearchRequest.facet_specs][google.cloud.retail.v2beta.SearchRequest.facet_specs] + and + [SearchRequest.boost_spec][google.cloud.retail.v2beta.SearchRequest.boost_spec] + for more details. + + This field is a member of `oneof`_ ``_indexable``. + """ + + text: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + numbers: MutableSequence[float] = proto.RepeatedField( + proto.DOUBLE, + number=2, + ) + searchable: bool = proto.Field( + proto.BOOL, + number=3, + optional=True, + ) + indexable: bool = proto.Field( + proto.BOOL, + number=4, + optional=True, + ) + + +class FulfillmentInfo(proto.Message): + r"""Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + Attributes: + type_ (str): + The fulfillment type, including commonly used types (such as + pickup in store and same day delivery), and custom types. + Customers have to map custom types to their display names + before rendering UI. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + place_ids (MutableSequence[str]): + The IDs for this + [type][google.cloud.retail.v2beta.FulfillmentInfo.type], + such as the store IDs for + [FulfillmentInfo.type.pickup-in-store][google.cloud.retail.v2beta.FulfillmentInfo.type] + or the region IDs for + [FulfillmentInfo.type.same-day-delivery][google.cloud.retail.v2beta.FulfillmentInfo.type]. + + A maximum of 3000 values are allowed. Each value must be a + string with a length limit of 30 characters, matching the + pattern ``[a-zA-Z0-9_-]+``, such as "store1" or "REGION-2". + Otherwise, an INVALID_ARGUMENT error is returned. + """ + + type_: str = proto.Field( + proto.STRING, + number=1, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + + +class Image(proto.Message): + r"""[Product][google.cloud.retail.v2beta.Product] image. Recommendations + AI and Retail Search do not use product images to improve prediction + and search results. However, product images can be returned in + results, and are shown in prediction or search previews in the + console. + + Attributes: + uri (str): + Required. URI of the image. + + This field must be a valid UTF-8 encoded URI with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + height (int): + Height of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + width (int): + Width of the image in number of pixels. + + This field must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + """ + + uri: str = proto.Field( + proto.STRING, + number=1, + ) + height: int = proto.Field( + proto.INT32, + number=2, + ) + width: int = proto.Field( + proto.INT32, + number=3, + ) + + +class Interval(proto.Message): + r"""A floating point interval. + + 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: + minimum (float): + Inclusive lower bound. + + This field is a member of `oneof`_ ``min``. + exclusive_minimum (float): + Exclusive lower bound. + + This field is a member of `oneof`_ ``min``. + maximum (float): + Inclusive upper bound. + + This field is a member of `oneof`_ ``max``. + exclusive_maximum (float): + Exclusive upper bound. + + This field is a member of `oneof`_ ``max``. + """ + + minimum: float = proto.Field( + proto.DOUBLE, + number=1, + oneof='min', + ) + exclusive_minimum: float = proto.Field( + proto.DOUBLE, + number=2, + oneof='min', + ) + maximum: float = proto.Field( + proto.DOUBLE, + number=3, + oneof='max', + ) + exclusive_maximum: float = proto.Field( + proto.DOUBLE, + number=4, + oneof='max', + ) + + +class PriceInfo(proto.Message): + r"""The price information of a + [Product][google.cloud.retail.v2beta.Product]. + + Attributes: + currency_code (str): + The 3-letter currency code defined in `ISO + 4217 `__. + + If this field is an unrecognizable currency code, an + INVALID_ARGUMENT error is returned. + + The + [Product.Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s with the same + [Product.primary_product_id][google.cloud.retail.v2beta.Product.primary_product_id] + must share the same + [currency_code][google.cloud.retail.v2beta.PriceInfo.currency_code]. + Otherwise, a FAILED_PRECONDITION error is returned. + price (float): + Price of the product. + + Google Merchant Center property + `price `__. + Schema.org property + `Offer.price `__. + original_price (float): + Price of the product without any discount. If zero, by + default set to be the + [price][google.cloud.retail.v2beta.PriceInfo.price]. If set, + [original_price][google.cloud.retail.v2beta.PriceInfo.original_price] + should be greater than or equal to + [price][google.cloud.retail.v2beta.PriceInfo.price], + otherwise an INVALID_ARGUMENT error is thrown. + cost (float): + The costs associated with the sale of a particular product. + Used for gross profit reporting. + + - Profit = + [price][google.cloud.retail.v2beta.PriceInfo.price] - + [cost][google.cloud.retail.v2beta.PriceInfo.cost] + + Google Merchant Center property + `cost_of_goods_sold `__. + price_effective_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2beta.PriceInfo.price] starts + to be effective. This can be set as a future timestamp, and + the [price][google.cloud.retail.v2beta.PriceInfo.price] is + only used for search after + [price_effective_time][google.cloud.retail.v2beta.PriceInfo.price_effective_time]. + If so, the + [original_price][google.cloud.retail.v2beta.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2beta.PriceInfo.original_price] + is used before + [price_effective_time][google.cloud.retail.v2beta.PriceInfo.price_effective_time]. + + Do not set if + [price][google.cloud.retail.v2beta.PriceInfo.price] is + always effective because it will cause additional latency + during search. + price_expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the + [price][google.cloud.retail.v2beta.PriceInfo.price] stops to + be effective. The + [price][google.cloud.retail.v2beta.PriceInfo.price] is used + for search before + [price_expire_time][google.cloud.retail.v2beta.PriceInfo.price_expire_time]. + If this field is set, the + [original_price][google.cloud.retail.v2beta.PriceInfo.original_price] + must be set and + [original_price][google.cloud.retail.v2beta.PriceInfo.original_price] + is used after + [price_expire_time][google.cloud.retail.v2beta.PriceInfo.price_expire_time]. + + Do not set if + [price][google.cloud.retail.v2beta.PriceInfo.price] is + always effective because it will cause additional latency + during search. + price_range (google.cloud.retail_v2beta.types.PriceInfo.PriceRange): + Output only. The price range of all the child + [Product.Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s grouped + together on the + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]. Only + populated for + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct]. + Do not set this field in API requests. + """ + + class PriceRange(proto.Message): + r"""The price range of all + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product] having the same + [Product.primary_product_id][google.cloud.retail.v2beta.Product.primary_product_id]. + + Attributes: + price (google.cloud.retail_v2beta.types.Interval): + The inclusive + [Product.pricing_info.price][google.cloud.retail.v2beta.PriceInfo.price] + interval of all + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product] having the + same + [Product.primary_product_id][google.cloud.retail.v2beta.Product.primary_product_id]. + original_price (google.cloud.retail_v2beta.types.Interval): + The inclusive + [Product.pricing_info.original_price][google.cloud.retail.v2beta.PriceInfo.original_price] + internal of all + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product] having the + same + [Product.primary_product_id][google.cloud.retail.v2beta.Product.primary_product_id]. + """ + + price: 'Interval' = proto.Field( + proto.MESSAGE, + number=1, + message='Interval', + ) + original_price: 'Interval' = proto.Field( + proto.MESSAGE, + number=2, + message='Interval', + ) + + currency_code: str = proto.Field( + proto.STRING, + number=1, + ) + price: float = proto.Field( + proto.FLOAT, + number=2, + ) + original_price: float = proto.Field( + proto.FLOAT, + number=3, + ) + cost: float = proto.Field( + proto.FLOAT, + number=4, + ) + price_effective_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + price_expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=6, + message=timestamp_pb2.Timestamp, + ) + price_range: PriceRange = proto.Field( + proto.MESSAGE, + number=7, + message=PriceRange, + ) + + +class Rating(proto.Message): + r"""The rating of a [Product][google.cloud.retail.v2beta.Product]. + + Attributes: + rating_count (int): + The total number of ratings. This value is independent of + the value of + [rating_histogram][google.cloud.retail.v2beta.Rating.rating_histogram]. + + This value must be nonnegative. Otherwise, an + INVALID_ARGUMENT error is returned. + average_rating (float): + The average rating of the + [Product][google.cloud.retail.v2beta.Product]. + + The rating is scaled at 1-5. Otherwise, an INVALID_ARGUMENT + error is returned. + rating_histogram (MutableSequence[int]): + List of rating counts per rating value (index = rating - 1). + The list is empty if there is no rating. If the list is + non-empty, its size is always 5. Otherwise, an + INVALID_ARGUMENT error is returned. + + For example, [41, 14, 13, 47, 303]. It means that the + [Product][google.cloud.retail.v2beta.Product] got 41 ratings + with 1 star, 14 ratings with 2 star, and so on. + """ + + rating_count: int = proto.Field( + proto.INT32, + number=1, + ) + average_rating: float = proto.Field( + proto.FLOAT, + number=2, + ) + rating_histogram: MutableSequence[int] = proto.RepeatedField( + proto.INT32, + number=3, + ) + + +class UserInfo(proto.Message): + r"""Information of an end user. + + Attributes: + user_id (str): + Highly recommended for logged-in users. Unique identifier + for logged-in user, such as a user name. Don't set for + anonymous users. + + Always use a hashed value for this ID. + + Don't set the field to the same fixed ID for different + users. This mixes the event history of those users together, + which results in degraded model quality. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + ip_address (str): + The end user's IP address. This field is used to extract + location information for personalization. + + This field must be either an IPv4 address (e.g. + "104.133.9.80") or an IPv6 address (e.g. + "2001:0db8:85a3:0000:0000:8a2e:0370:7334"). Otherwise, an + INVALID_ARGUMENT error is returned. + + This should not be set when: + + - setting + [SearchRequest.user_info][google.cloud.retail.v2beta.SearchRequest.user_info]. + - using the JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2beta.UserEventService.CollectUserEvent] + or if + [direct_user_request][google.cloud.retail.v2beta.UserInfo.direct_user_request] + is set. + user_agent (str): + User agent as included in the HTTP header. Required for + getting + [SearchResponse.sponsored_results][google.cloud.retail.v2beta.SearchResponse.sponsored_results]. + + The field must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This should not be set when using the client side event + reporting with GTM or JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2beta.UserEventService.CollectUserEvent] + or if + [direct_user_request][google.cloud.retail.v2beta.UserInfo.direct_user_request] + is set. + direct_user_request (bool): + True if the request is made directly from the end user, in + which case the + [ip_address][google.cloud.retail.v2beta.UserInfo.ip_address] + and + [user_agent][google.cloud.retail.v2beta.UserInfo.user_agent] + can be populated from the HTTP request. This flag should be + set only if the API request is made directly from the end + user such as a mobile app (and not if a gateway or a server + is processing and pushing the user events). + + This should not be set when using the JavaScript tag in + [UserEventService.CollectUserEvent][google.cloud.retail.v2beta.UserEventService.CollectUserEvent]. + """ + + user_id: str = proto.Field( + proto.STRING, + number=1, + ) + ip_address: str = proto.Field( + proto.STRING, + number=2, + ) + user_agent: str = proto.Field( + proto.STRING, + number=3, + ) + direct_user_request: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class LocalInventory(proto.Message): + r"""The inventory information at a place (e.g. a store) + identified by a place ID. + + Attributes: + place_id (str): + The place ID for the current set of inventory + information. + price_info (google.cloud.retail_v2beta.types.PriceInfo): + Product price and cost information. + + Google Merchant Center property + `price `__. + attributes (MutableMapping[str, google.cloud.retail_v2beta.types.CustomAttribute]): + Additional local inventory attributes, for example, store + name, promotion tags, etc. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - At most 30 attributes are allowed. + - The key must be a UTF-8 encoded string with a length + limit of 32 characters. + - The key must match the pattern: + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, key0LikeThis + or KEY_1_LIKE_THIS. + - The attribute values must be of the same type (text or + number). + - Only 1 value is allowed for each attribute. + - For text values, the length limit is 256 UTF-8 + characters. + - The attribute does not support search. The ``searchable`` + field should be unset or set to false. + - The max summed total bytes of custom attribute keys and + values per product is 5MiB. + fulfillment_types (MutableSequence[str]): + Input only. Supported fulfillment types. Valid fulfillment + type values include commonly used types (such as pickup in + store and same day delivery), and custom types. Customers + have to map custom types to their display names before + rendering UI. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + All the elements must be distinct. Otherwise, an + INVALID_ARGUMENT error is returned. + """ + + place_id: str = proto.Field( + proto.STRING, + number=1, + ) + price_info: 'PriceInfo' = proto.Field( + proto.MESSAGE, + number=2, + message='PriceInfo', + ) + attributes: MutableMapping[str, 'CustomAttribute'] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=3, + message='CustomAttribute', + ) + fulfillment_types: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/completion_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/completion_service.py new file mode 100644 index 00000000..46d70c30 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/completion_service.py @@ -0,0 +1,251 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'CompleteQueryRequest', + 'CompleteQueryResponse', + }, +) + + +class CompleteQueryRequest(proto.Message): + r"""Autocomplete parameters. + + Attributes: + catalog (str): + Required. Catalog for which the completion is performed. + + Full resource name of catalog, such as + ``projects/*/locations/global/catalogs/default_catalog``. + query (str): + Required. The query used to generate + suggestions. + The maximum number of allowed characters is 255. + visitor_id (str): + Required field. A unique identifier for tracking visitors. + For example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor logs in or out of the website. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + language_codes (MutableSequence[str]): + Note that this field applies for ``user-data`` dataset only. + For requests with ``cloud-retail`` dataset, setting this + field has no effect. + + The language filters applied to the output suggestions. If + set, it should contain the language of the query. If not + set, suggestions are returned without considering language + restrictions. This is the BCP-47 language code, such as + "en-US" or "sr-Latn". For more information, see `Tags for + Identifying + Languages `__. The + maximum number of language codes is 3. + device_type (str): + The device type context for completion suggestions. We + recommend that you leave this field empty. + + It can apply different suggestions on different device + types, e.g. ``DESKTOP``, ``MOBILE``. If it is empty, the + suggestions are across all device types. + + Supported formats: + + - ``UNKNOWN_DEVICE_TYPE`` + + - ``DESKTOP`` + + - ``MOBILE`` + + - A customized string starts with ``OTHER_``, e.g. + ``OTHER_IPHONE``. + dataset (str): + Determines which dataset to use for fetching completion. + "user-data" will use the imported dataset through + [CompletionService.ImportCompletionData][google.cloud.retail.v2beta.CompletionService.ImportCompletionData]. + "cloud-retail" will use the dataset generated by cloud + retail based on user events. If leave empty, it will use the + "user-data". + + Current supported values: + + - user-data + + - cloud-retail: This option requires enabling auto-learning + function first. See + `guidelines `__. + max_suggestions (int): + Completion max suggestions. If left unset or set to 0, then + will fallback to the configured value + [CompletionConfig.max_suggestions][google.cloud.retail.v2beta.CompletionConfig.max_suggestions]. + + The maximum allowed max suggestions is 20. If it is set + higher, it will be capped by 20. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2beta.UserEvent.entity] + to get per-entity autocomplete results. + """ + + catalog: str = proto.Field( + proto.STRING, + number=1, + ) + query: str = proto.Field( + proto.STRING, + number=2, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=7, + ) + language_codes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + device_type: str = proto.Field( + proto.STRING, + number=4, + ) + dataset: str = proto.Field( + proto.STRING, + number=6, + ) + max_suggestions: int = proto.Field( + proto.INT32, + number=5, + ) + entity: str = proto.Field( + proto.STRING, + number=10, + ) + + +class CompleteQueryResponse(proto.Message): + r"""Response of the autocomplete query. + + Attributes: + completion_results (MutableSequence[google.cloud.retail_v2beta.types.CompleteQueryResponse.CompletionResult]): + Results of the matching suggestions. The + result list is ordered and the first result is + top suggestion. + attribution_token (str): + A unique complete token. This should be included in the + [UserEvent.completion_detail][google.cloud.retail.v2beta.UserEvent.completion_detail] + for search events resulting from this completion, which + enables accurate attribution of complete model performance. + recent_search_results (MutableSequence[google.cloud.retail_v2beta.types.CompleteQueryResponse.RecentSearchResult]): + Matched recent searches of this user. The maximum number of + recent searches is 10. This field is a restricted feature. + Contact Retail Search support team if you are interested in + enabling it. + + This feature is only available when + [CompleteQueryRequest.visitor_id][google.cloud.retail.v2beta.CompleteQueryRequest.visitor_id] + field is set and + [UserEvent][google.cloud.retail.v2beta.UserEvent] is + imported. The recent searches satisfy the follow rules: + + - They are ordered from latest to oldest. + + - They are matched with + [CompleteQueryRequest.query][google.cloud.retail.v2beta.CompleteQueryRequest.query] + case insensitively. + + - They are transformed to lower case. + + - They are UTF-8 safe. + + Recent searches are deduplicated. More recent searches will + be reserved when duplication happens. + """ + + class CompletionResult(proto.Message): + r"""Resource that represents completion results. + + Attributes: + suggestion (str): + The suggestion for the query. + attributes (MutableMapping[str, google.cloud.retail_v2beta.types.CustomAttribute]): + Custom attributes for the suggestion term. + + - For "user-data", the attributes are additional custom + attributes ingested through BigQuery. + + - For "cloud-retail", the attributes are product attributes + generated by Cloud Retail. It requires + [UserEvent.product_details][google.cloud.retail.v2beta.UserEvent.product_details] + is imported properly. + """ + + suggestion: str = proto.Field( + proto.STRING, + number=1, + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message=common.CustomAttribute, + ) + + class RecentSearchResult(proto.Message): + r"""Recent search of this user. + + Attributes: + recent_search (str): + The recent search query. + """ + + recent_search: str = proto.Field( + proto.STRING, + number=1, + ) + + completion_results: MutableSequence[CompletionResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=CompletionResult, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=2, + ) + recent_search_results: MutableSequence[RecentSearchResult] = proto.RepeatedField( + proto.MESSAGE, + number=3, + message=RecentSearchResult, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control.py new file mode 100644 index 00000000..10ff076e --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control.py @@ -0,0 +1,134 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import search_service + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'Control', + }, +) + + +class Control(proto.Message): + r"""Configures dynamic metadata that can be linked to a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] and affect + search or recommendation results at serving time. + + 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: + facet_spec (google.cloud.retail_v2beta.types.SearchRequest.FacetSpec): + A facet specification to perform faceted search. + + Note that this field is deprecated and will throw + NOT_IMPLEMENTED if used for creating a control. + + This field is a member of `oneof`_ ``control``. + rule (google.cloud.retail_v2beta.types.Rule): + A rule control - a condition-action pair. + Enacts a set action when the condition is + triggered. For example: Boost "gShoe" when query + full matches "Running Shoes". + + This field is a member of `oneof`_ ``control``. + name (str): + Immutable. Fully qualified name + ``projects/*/locations/global/catalogs/*/controls/*`` + display_name (str): + Required. The human readable control display name. Used in + Retail UI. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is thrown. + associated_serving_config_ids (MutableSequence[str]): + Output only. List of [serving + config][google.cloud.retail.v2beta.ServingConfig] ids that + are associated with this control in the same + [Catalog][google.cloud.retail.v2beta.Catalog]. + + Note the association is managed via the + [ServingConfig][google.cloud.retail.v2beta.ServingConfig], + this is an output only denormalized view. + solution_types (MutableSequence[google.cloud.retail_v2beta.types.SolutionType]): + Required. Immutable. The solution types that the control is + used for. Currently we support setting only one type of + solution at creation time. + + Only ``SOLUTION_TYPE_SEARCH`` value is supported at the + moment. If no solution type is provided at creation time, + will default to + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2beta.SolutionType.SOLUTION_TYPE_SEARCH]. + search_solution_use_case (MutableSequence[google.cloud.retail_v2beta.types.SearchSolutionUseCase]): + Specifies the use case for the control. Affects what + condition fields can be set. Only settable by search + controls. Will default to + [SEARCH_SOLUTION_USE_CASE_SEARCH][google.cloud.retail.v2beta.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + if not specified. Currently only allow one + search_solution_use_case per control. + """ + + facet_spec: search_service.SearchRequest.FacetSpec = proto.Field( + proto.MESSAGE, + number=3, + oneof='control', + message=search_service.SearchRequest.FacetSpec, + ) + rule: common.Rule = proto.Field( + proto.MESSAGE, + number=4, + oneof='control', + message=common.Rule, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + associated_serving_config_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + solution_types: MutableSequence[common.SolutionType] = proto.RepeatedField( + proto.ENUM, + number=6, + enum=common.SolutionType, + ) + search_solution_use_case: MutableSequence[common.SearchSolutionUseCase] = proto.RepeatedField( + proto.ENUM, + number=7, + enum=common.SearchSolutionUseCase, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control_service.py new file mode 100644 index 00000000..2659f3e7 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/control_service.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 __future__ import annotations + +from typing import MutableMapping, MutableSequence + +import proto # type: ignore + +from google.cloud.retail_v2beta.types import control as gcr_control +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'CreateControlRequest', + 'UpdateControlRequest', + 'DeleteControlRequest', + 'GetControlRequest', + 'ListControlsRequest', + 'ListControlsResponse', + }, +) + + +class CreateControlRequest(proto.Message): + r"""Request for CreateControl method. + + Attributes: + parent (str): + Required. Full resource name of parent catalog. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + control (google.cloud.retail_v2beta.types.Control): + Required. The Control to create. + control_id (str): + Required. The ID to use for the Control, which will become + the final component of the Control's resource name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-_/. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + control: gcr_control.Control = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_control.Control, + ) + control_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class UpdateControlRequest(proto.Message): + r"""Request for UpdateControl method. + + Attributes: + control (google.cloud.retail_v2beta.types.Control): + Required. The Control to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Control][google.cloud.retail.v2beta.Control] to update. The + following are NOT supported: + + - [Control.name][google.cloud.retail.v2beta.Control.name] + + If not set or empty, all supported fields are updated. + """ + + control: gcr_control.Control = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_control.Control, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteControlRequest(proto.Message): + r"""Request for DeleteControl method. + + Attributes: + name (str): + Required. The resource name of the Control to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetControlRequest(proto.Message): + r"""Request for GetControl method. + + Attributes: + name (str): + Required. The resource name of the Control to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/controls/{control_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListControlsRequest(proto.Message): + r"""Request for ListControls method. + + Attributes: + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 50. Max + allowed value is 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListControls`` call. Provide this to retrieve the + subsequent page. + filter (str): + Optional. A filter to apply on the list results. Supported + features: + + - List all the products under the parent branch if + [filter][google.cloud.retail.v2beta.ListControlsRequest.filter] + is unset. + - List controls that are used in a single ServingConfig: + 'serving_config = "boosted_home_page_cvr"' + """ + + 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, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ListControlsResponse(proto.Message): + r"""Response for ListControls method. + + Attributes: + controls (MutableSequence[google.cloud.retail_v2beta.types.Control]): + All the Controls for a given catalog. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + controls: MutableSequence[gcr_control.Control] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_control.Control, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/export_config.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/export_config.py new file mode 100644 index 00000000..72e0b24d --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/export_config.py @@ -0,0 +1,214 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.protobuf import timestamp_pb2 # type: ignore +from google.rpc import status_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'ExportErrorsConfig', + 'ExportMetadata', + 'ExportProductsResponse', + 'ExportUserEventsResponse', + 'OutputResult', + 'BigQueryOutputResult', + 'GcsOutputResult', + }, +) + + +class ExportErrorsConfig(proto.Message): + r"""Configuration of destination for Export related errors. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_prefix (str): + Google Cloud Storage path for import errors. This must be an + empty, existing Cloud Storage bucket. Export errors will be + written to a file in this bucket, one per line, as a + JSON-encoded ``google.rpc.Status`` message. + + This field is a member of `oneof`_ ``destination``. + """ + + gcs_prefix: str = proto.Field( + proto.STRING, + number=1, + oneof='destination', + ) + + +class ExportMetadata(proto.Message): + r"""Metadata related to the progress of the Export operation. + This is returned by the google.longrunning.Operation.metadata + field. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + + +class ExportProductsResponse(proto.Message): + r"""Response of the ExportProductsRequest. If the long running + operation is done, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2beta.types.ExportErrorsConfig): + This field is never set. + output_result (google.cloud.retail_v2beta.types.OutputResult): + Output result indicating where the data were + exported to. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ExportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ExportErrorsConfig', + ) + output_result: 'OutputResult' = proto.Field( + proto.MESSAGE, + number=3, + message='OutputResult', + ) + + +class ExportUserEventsResponse(proto.Message): + r"""Response of the ExportUserEventsRequest. If the long running + operation was successful, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2beta.types.ExportErrorsConfig): + This field is never set. + output_result (google.cloud.retail_v2beta.types.OutputResult): + Output result indicating where the data were + exported to. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ExportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ExportErrorsConfig', + ) + output_result: 'OutputResult' = proto.Field( + proto.MESSAGE, + number=3, + message='OutputResult', + ) + + +class OutputResult(proto.Message): + r"""Output result that stores the information about where the + exported data is stored. + + Attributes: + bigquery_result (MutableSequence[google.cloud.retail_v2beta.types.BigQueryOutputResult]): + The BigQuery location where the result is + stored. + gcs_result (MutableSequence[google.cloud.retail_v2beta.types.GcsOutputResult]): + The Google Cloud Storage location where the + result is stored. + """ + + bigquery_result: MutableSequence['BigQueryOutputResult'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='BigQueryOutputResult', + ) + gcs_result: MutableSequence['GcsOutputResult'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='GcsOutputResult', + ) + + +class BigQueryOutputResult(proto.Message): + r"""A BigQuery output result. + + Attributes: + dataset_id (str): + The ID of a BigQuery Dataset. + table_id (str): + The ID of a BigQuery Table. + """ + + dataset_id: str = proto.Field( + proto.STRING, + number=1, + ) + table_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class GcsOutputResult(proto.Message): + r"""A Gcs output result. + + Attributes: + output_uri (str): + The uri of Gcs output + """ + + output_uri: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/import_config.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/import_config.py new file mode 100644 index 00000000..300fc84a --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/import_config.py @@ -0,0 +1,704 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import user_event +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 google.type import date_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'GcsSource', + 'BigQuerySource', + 'ProductInlineSource', + 'UserEventInlineSource', + 'ImportErrorsConfig', + 'ImportProductsRequest', + 'ImportUserEventsRequest', + 'ImportCompletionDataRequest', + 'ProductInputConfig', + 'UserEventInputConfig', + 'CompletionDataInputConfig', + 'ImportMetadata', + 'ImportProductsResponse', + 'ImportUserEventsResponse', + 'UserEventImportSummary', + 'ImportCompletionDataResponse', + }, +) + + +class GcsSource(proto.Message): + r"""Google Cloud Storage location for input content. + + Attributes: + input_uris (MutableSequence[str]): + Required. Google Cloud Storage URIs to input files. URI can + be up to 2000 characters long. URIs can match the full + object path (for example, + ``gs://bucket/directory/object.json``) or a pattern matching + one or more files, such as ``gs://bucket/directory/*.json``. + A request can contain at most 100 files, and each file can + be up to 2 GB. See `Importing product + information `__ + for the expected file format and setup instructions. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2beta.Product] per line. + Each product must have a valid + [Product.id][google.cloud.retail.v2beta.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2beta.UserEvent] per + line. + - ``user_event_ga360``: Using + https://support.google.com/analytics/answer/3437719. + + Supported values for control imports: + + - ``control`` (default): One JSON + [Control][google.cloud.retail.v2beta.Control] per line. + + Supported values for catalog attribute imports: + + - ``catalog_attribute`` (default): One CSV + [CatalogAttribute][google.cloud.retail.v2beta.CatalogAttribute] + per line. + """ + + input_uris: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + data_schema: str = proto.Field( + proto.STRING, + number=2, + ) + + +class BigQuerySource(proto.Message): + r"""BigQuery source import data from. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + partition_date (google.type.date_pb2.Date): + BigQuery time partitioned table's \_PARTITIONDATE in + YYYY-MM-DD format. + + Only supported in + [ImportProductsRequest][google.cloud.retail.v2beta.ImportProductsRequest]. + + This field is a member of `oneof`_ ``partition``. + project_id (str): + The project ID (can be project # or ID) that + the BigQuery source is in with a length limit of + 128 characters. If not specified, inherits the + project ID from the parent request. + dataset_id (str): + Required. The BigQuery data set to copy the + data from with a length limit of 1,024 + characters. + table_id (str): + Required. The BigQuery table to copy the data + from with a length limit of 1,024 characters. + gcs_staging_dir (str): + Intermediate Cloud Storage directory used for + the import with a length limit of 2,000 + characters. Can be specified if one wants to + have the BigQuery export to a specific Cloud + Storage directory. + data_schema (str): + The schema to use when parsing the data from the source. + + Supported values for product imports: + + - ``product`` (default): One JSON + [Product][google.cloud.retail.v2beta.Product] per line. + Each product must have a valid + [Product.id][google.cloud.retail.v2beta.Product.id]. + - ``product_merchant_center``: See `Importing catalog data + from Merchant + Center `__. + + Supported values for user events imports: + + - ``user_event`` (default): One JSON + [UserEvent][google.cloud.retail.v2beta.UserEvent] per + line. + - ``user_event_ga360``: The schema is available here: + https://support.google.com/analytics/answer/3437719. + - ``user_event_ga4``: The schema is available here: + https://support.google.com/analytics/answer/7029846. + + Supported values for autocomplete imports: + + - ``suggestions`` (default): One JSON completion suggestion + per line. + - ``denylist``: One JSON deny suggestion per line. + - ``allowlist``: One JSON allow suggestion per line. + """ + + partition_date: date_pb2.Date = proto.Field( + proto.MESSAGE, + number=6, + oneof='partition', + message=date_pb2.Date, + ) + project_id: str = proto.Field( + proto.STRING, + number=5, + ) + dataset_id: str = proto.Field( + proto.STRING, + number=1, + ) + table_id: str = proto.Field( + proto.STRING, + number=2, + ) + gcs_staging_dir: str = proto.Field( + proto.STRING, + number=3, + ) + data_schema: str = proto.Field( + proto.STRING, + number=4, + ) + + +class ProductInlineSource(proto.Message): + r"""The inline source for the input config for ImportProducts + method. + + Attributes: + products (MutableSequence[google.cloud.retail_v2beta.types.Product]): + Required. A list of products to update/create. Each product + must have a valid + [Product.id][google.cloud.retail.v2beta.Product.id]. + Recommended max of 100 items. + """ + + products: MutableSequence[product.Product] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=product.Product, + ) + + +class UserEventInlineSource(proto.Message): + r"""The inline source for the input config for ImportUserEvents + method. + + Attributes: + user_events (MutableSequence[google.cloud.retail_v2beta.types.UserEvent]): + Required. A list of user events to import. + Recommended max of 10k items. + """ + + user_events: MutableSequence[user_event.UserEvent] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=user_event.UserEvent, + ) + + +class ImportErrorsConfig(proto.Message): + r"""Configuration of destination for Import related errors. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + gcs_prefix (str): + Google Cloud Storage prefix for import errors. This must be + an empty, existing Cloud Storage directory. Import errors + are written to sharded files in this directory, one per + line, as a JSON-encoded ``google.rpc.Status`` message. + + This field is a member of `oneof`_ ``destination``. + """ + + gcs_prefix: str = proto.Field( + proto.STRING, + number=1, + oneof='destination', + ) + + +class ImportProductsRequest(proto.Message): + r"""Request message for Import methods. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog/branches/default_branch`` + + If no updateMask is specified, requires products.create + permission. If updateMask is specified, requires + products.update permission. + request_id (str): + Deprecated. This field has no effect. + input_config (google.cloud.retail_v2beta.types.ProductInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2beta.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided imported ``products`` + to update. If not set, all fields are updated. + reconciliation_mode (google.cloud.retail_v2beta.types.ImportProductsRequest.ReconciliationMode): + The mode of reconciliation between existing products and the + products to be imported. Defaults to + [ReconciliationMode.INCREMENTAL][google.cloud.retail.v2beta.ImportProductsRequest.ReconciliationMode.INCREMENTAL]. + notification_pubsub_topic (str): + Full Pub/Sub topic name for receiving notification. If this + field is set, when the import is finished, a notification is + sent to specified Pub/Sub topic. The message data is JSON + string of a [Operation][google.longrunning.Operation]. + + Format of the Pub/Sub topic is + ``projects/{project}/topics/{topic}``. It has to be within + the same project as + [ImportProductsRequest.parent][google.cloud.retail.v2beta.ImportProductsRequest.parent]. + Make sure that + ``service-@gcp-sa-retail.iam.gserviceaccount.com`` + has the ``pubsub.topics.publish`` IAM permission on the + topic. + """ + class ReconciliationMode(proto.Enum): + r"""Indicates how imported products are reconciled with the + existing products created or imported before. + + Values: + RECONCILIATION_MODE_UNSPECIFIED (0): + Defaults to INCREMENTAL. + INCREMENTAL (1): + Inserts new products or updates existing + products. + FULL (2): + Calculates diff and replaces the entire + product dataset. Existing products may be + deleted if they are not present in the source + location. + """ + RECONCILIATION_MODE_UNSPECIFIED = 0 + INCREMENTAL = 1 + FULL = 2 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + request_id: str = proto.Field( + proto.STRING, + number=6, + ) + input_config: 'ProductInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ProductInputConfig', + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=3, + message='ImportErrorsConfig', + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + reconciliation_mode: ReconciliationMode = proto.Field( + proto.ENUM, + number=5, + enum=ReconciliationMode, + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=7, + ) + + +class ImportUserEventsRequest(proto.Message): + r"""Request message for the ImportUserEvents request. + + Attributes: + parent (str): + Required. + ``projects/1234/locations/global/catalogs/default_catalog`` + input_config (google.cloud.retail_v2beta.types.UserEventInputConfig): + Required. The desired input location of the + data. + errors_config (google.cloud.retail_v2beta.types.ImportErrorsConfig): + The desired location of errors incurred + during the Import. Cannot be set for inline user + event imports. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'UserEventInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='UserEventInputConfig', + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=3, + message='ImportErrorsConfig', + ) + + +class ImportCompletionDataRequest(proto.Message): + r"""Request message for ImportCompletionData methods. + + Attributes: + parent (str): + Required. The catalog which the suggestions dataset belongs + to. + + Format: + ``projects/1234/locations/global/catalogs/default_catalog``. + input_config (google.cloud.retail_v2beta.types.CompletionDataInputConfig): + Required. The desired input location of the + data. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + input_config: 'CompletionDataInputConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='CompletionDataInputConfig', + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=3, + ) + + +class ProductInputConfig(proto.Message): + r"""The input config source for products. + + 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_inline_source (google.cloud.retail_v2beta.types.ProductInlineSource): + The Inline source for the input content for + products. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2beta.types.GcsSource): + Google Cloud Storage location for the input + content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2beta.types.BigQuerySource): + BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + product_inline_source: 'ProductInlineSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='ProductInlineSource', + ) + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class UserEventInputConfig(proto.Message): + r"""The input config source for user events. + + 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: + user_event_inline_source (google.cloud.retail_v2beta.types.UserEventInlineSource): + Required. The Inline source for the input + content for UserEvents. + + This field is a member of `oneof`_ ``source``. + gcs_source (google.cloud.retail_v2beta.types.GcsSource): + Required. Google Cloud Storage location for + the input content. + + This field is a member of `oneof`_ ``source``. + big_query_source (google.cloud.retail_v2beta.types.BigQuerySource): + Required. BigQuery input source. + + This field is a member of `oneof`_ ``source``. + """ + + user_event_inline_source: 'UserEventInlineSource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='UserEventInlineSource', + ) + gcs_source: 'GcsSource' = proto.Field( + proto.MESSAGE, + number=2, + oneof='source', + message='GcsSource', + ) + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=3, + oneof='source', + message='BigQuerySource', + ) + + +class CompletionDataInputConfig(proto.Message): + r"""The input config source for completion data. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + big_query_source (google.cloud.retail_v2beta.types.BigQuerySource): + Required. BigQuery input source. + + Add the IAM permission "BigQuery Data Viewer" + for + cloud-retail-customer-data-access@system.gserviceaccount.com + before using this feature otherwise an error is + thrown. + + This field is a member of `oneof`_ ``source``. + """ + + big_query_source: 'BigQuerySource' = proto.Field( + proto.MESSAGE, + number=1, + oneof='source', + message='BigQuerySource', + ) + + +class ImportMetadata(proto.Message): + r"""Metadata related to the progress of the Import operation. + This is returned by the google.longrunning.Operation.metadata + field. + + Attributes: + create_time (google.protobuf.timestamp_pb2.Timestamp): + Operation create time. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Operation last update time. If the operation + is done, this is also the finish time. + success_count (int): + Count of entries that were processed + successfully. + failure_count (int): + Count of entries that encountered errors + while processing. + request_id (str): + Deprecated. This field is never set. + notification_pubsub_topic (str): + Pub/Sub topic for receiving notification. If this field is + set, when the import is finished, a notification is sent to + specified Pub/Sub topic. The message data is JSON string of + a [Operation][google.longrunning.Operation]. Format of the + Pub/Sub topic is ``projects/{project}/topics/{topic}``. + """ + + create_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=1, + message=timestamp_pb2.Timestamp, + ) + update_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=2, + message=timestamp_pb2.Timestamp, + ) + success_count: int = proto.Field( + proto.INT64, + number=3, + ) + failure_count: int = proto.Field( + proto.INT64, + number=4, + ) + request_id: str = proto.Field( + proto.STRING, + number=5, + ) + notification_pubsub_topic: str = proto.Field( + proto.STRING, + number=6, + ) + + +class ImportProductsResponse(proto.Message): + r"""Response of the + [ImportProductsRequest][google.cloud.retail.v2beta.ImportProductsRequest]. + If the long running operation is done, then this message is returned + by the google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2beta.types.ImportErrorsConfig): + Echoes the destination for the complete + errors in the request if set. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + + +class ImportUserEventsResponse(proto.Message): + r"""Response of the ImportUserEventsRequest. If the long running + operation was successful, then this message is returned by the + google.longrunning.Operations.response field if the operation + was successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + errors_config (google.cloud.retail_v2beta.types.ImportErrorsConfig): + Echoes the destination for the complete + errors if this field was set in the request. + import_summary (google.cloud.retail_v2beta.types.UserEventImportSummary): + Aggregated statistics of user event import + status. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + errors_config: 'ImportErrorsConfig' = proto.Field( + proto.MESSAGE, + number=2, + message='ImportErrorsConfig', + ) + import_summary: 'UserEventImportSummary' = proto.Field( + proto.MESSAGE, + number=3, + message='UserEventImportSummary', + ) + + +class UserEventImportSummary(proto.Message): + r"""A summary of import result. The UserEventImportSummary + summarizes the import status for user events. + + Attributes: + joined_events_count (int): + Count of user events imported with complete + existing catalog information. + unjoined_events_count (int): + Count of user events imported, but with + catalog information not found in the imported + catalog. + """ + + joined_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + unjoined_events_count: int = proto.Field( + proto.INT64, + number=2, + ) + + +class ImportCompletionDataResponse(proto.Message): + r"""Response of the + [ImportCompletionDataRequest][google.cloud.retail.v2beta.ImportCompletionDataRequest]. + If the long running operation is done, this message is returned by + the google.longrunning.Operations.response field if the operation is + successful. + + Attributes: + error_samples (MutableSequence[google.rpc.status_pb2.Status]): + A sample of errors encountered while + processing the request. + """ + + error_samples: MutableSequence[status_pb2.Status] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=status_pb2.Status, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model.py new file mode 100644 index 00000000..4e8b26f5 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model.py @@ -0,0 +1,320 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'Model', + }, +) + + +class Model(proto.Message): + r"""Metadata that describes the training and serving parameters of a + [Model][google.cloud.retail.v2beta.Model]. A + [Model][google.cloud.retail.v2beta.Model] can be associated with a + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] and then + queried through the Predict API. + + Attributes: + name (str): + Required. The fully qualified resource name of the model. + + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + catalog_id has char limit of 50. recommendation_model_id has + char limit of 40. + display_name (str): + Required. The display name of the model. + + Should be human readable, used to display + Recommendation Models in the Retail Cloud + Console Dashboard. UTF-8 encoded string with + limit of 1024 characters. + training_state (google.cloud.retail_v2beta.types.Model.TrainingState): + Optional. The training state that the model is in (e.g. + ``TRAINING`` or ``PAUSED``). + + Since part of the cost of running the service is frequency + of training - this can be used to determine when to train + model in order to control cost. If not specified: the + default value for ``CreateModel`` method is ``TRAINING``. + The default value for ``UpdateModel`` method is to keep the + state the same as before. + serving_state (google.cloud.retail_v2beta.types.Model.ServingState): + Output only. The serving state of the model: ``ACTIVE``, + ``NOT_ACTIVE``. + create_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was created at. + update_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. Timestamp the Recommendation + Model was last updated. E.g. if a Recommendation + Model was paused - this would be the time the + pause was initiated. + type_ (str): + Required. The type of model e.g. ``home-page``. + + Currently supported values: ``recommended-for-you``, + ``others-you-may-like``, ``frequently-bought-together``, + ``page-optimization``, ``similar-items``, ``buy-it-again``, + ``on-sale-items``, and ``recently-viewed``\ (readonly + value). + + This field together with + [optimization_objective][google.cloud.retail.v2beta.Model.optimization_objective] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + optimization_objective (str): + Optional. The optimization objective e.g. ``cvr``. + + Currently supported values: ``ctr``, ``cvr``, + ``revenue-per-order``. + + If not specified, we choose default based on model type. + Default depends on type of recommendation: + + ``recommended-for-you`` => ``ctr`` + + ``others-you-may-like`` => ``ctr`` + + ``frequently-bought-together`` => ``revenue_per_order`` + + This field together with + [optimization_objective][google.cloud.retail.v2beta.Model.type] + describe model metadata to use to control model training and + serving. See https://cloud.google.com/retail/docs/models for + more details on what the model metadata control and which + combination of parameters are valid. For invalid + combinations of parameters (e.g. type = + ``frequently-bought-together`` and optimization_objective = + ``ctr``), you receive an error 400 if you try to + create/update a recommendation with this set of knobs. + periodic_tuning_state (google.cloud.retail_v2beta.types.Model.PeriodicTuningState): + Optional. The state of periodic tuning. + + The period we use is 3 months - to do a one-off tune earlier + use the ``TuneModel`` method. Default value is + ``PERIODIC_TUNING_ENABLED``. + last_tune_time (google.protobuf.timestamp_pb2.Timestamp): + Output only. The timestamp when the latest + successful tune finished. + tuning_operation (str): + Output only. The tune operation associated + with the model. + Can be used to determine if there is an ongoing + tune for this recommendation. Empty field + implies no tune is goig on. + data_state (google.cloud.retail_v2beta.types.Model.DataState): + Output only. The state of data requirements for this model: + ``DATA_OK`` and ``DATA_ERROR``. + + Recommendation model cannot be trained if the data is in + ``DATA_ERROR`` state. Recommendation model can have + ``DATA_ERROR`` state even if serving state is ``ACTIVE``: + models were trained successfully before, but cannot be + refreshed because model no longer has sufficient data for + training. + filtering_option (google.cloud.retail_v2beta.types.RecommendationsFilteringOption): + Optional. If ``RECOMMENDATIONS_FILTERING_ENABLED``, + recommendation filtering by attributes is enabled for the + model. + serving_config_lists (MutableSequence[google.cloud.retail_v2beta.types.Model.ServingConfigList]): + Output only. The list of valid serving + configs associated with the + PageOptimizationConfig. + """ + class ServingState(proto.Enum): + r"""The serving state of the model. + + Values: + SERVING_STATE_UNSPECIFIED (0): + Unspecified serving state. + INACTIVE (1): + The model is not serving. + ACTIVE (2): + The model is serving and can be queried. + TUNED (3): + The model is trained on tuned hyperparameters + and can be queried. + """ + SERVING_STATE_UNSPECIFIED = 0 + INACTIVE = 1 + ACTIVE = 2 + TUNED = 3 + + class TrainingState(proto.Enum): + r"""The training state of the model. + + Values: + TRAINING_STATE_UNSPECIFIED (0): + Unspecified training state. + PAUSED (1): + The model training is paused. + TRAINING (2): + The model is training. + """ + TRAINING_STATE_UNSPECIFIED = 0 + PAUSED = 1 + TRAINING = 2 + + class PeriodicTuningState(proto.Enum): + r"""Describes whether periodic tuning is enabled for this model or not. + Periodic tuning is scheduled at most every three months. You can + start a tuning process manually by using the ``TuneModel`` method, + which starts a tuning process immediately and resets the quarterly + schedule. Enabling or disabling periodic tuning does not affect any + current tuning processes. + + Values: + PERIODIC_TUNING_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + PERIODIC_TUNING_DISABLED (1): + The model has periodic tuning disabled. Tuning can be + reenabled by calling the ``EnableModelPeriodicTuning`` + method or by calling the ``TuneModel`` method. + ALL_TUNING_DISABLED (3): + The model cannot be tuned with periodic tuning OR the + ``TuneModel`` method. Hide the options in customer UI and + reject any requests through the backend self serve API. + PERIODIC_TUNING_ENABLED (2): + The model has periodic tuning enabled. Tuning can be + disabled by calling the ``DisableModelPeriodicTuning`` + method. + """ + PERIODIC_TUNING_STATE_UNSPECIFIED = 0 + PERIODIC_TUNING_DISABLED = 1 + ALL_TUNING_DISABLED = 3 + PERIODIC_TUNING_ENABLED = 2 + + class DataState(proto.Enum): + r"""Describes whether this model have sufficient training data + to be continuously trained. + + Values: + DATA_STATE_UNSPECIFIED (0): + Unspecified default value, should never be + explicitly set. + DATA_OK (1): + The model has sufficient training data. + DATA_ERROR (2): + The model does not have sufficient training + data. Error messages can be queried via + Stackdriver. + """ + DATA_STATE_UNSPECIFIED = 0 + DATA_OK = 1 + DATA_ERROR = 2 + + class ServingConfigList(proto.Message): + r"""Represents an ordered combination of valid serving configs, which + can be used for ``PAGE_OPTIMIZATION`` recommendations. + + Attributes: + serving_config_ids (MutableSequence[str]): + Optional. A set of valid serving configs that may be used + for ``PAGE_OPTIMIZATION``. + """ + + serving_config_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=1, + ) + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + training_state: TrainingState = proto.Field( + proto.ENUM, + number=3, + enum=TrainingState, + ) + serving_state: ServingState = proto.Field( + proto.ENUM, + number=4, + enum=ServingState, + ) + 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, + ) + type_: str = proto.Field( + proto.STRING, + number=7, + ) + optimization_objective: str = proto.Field( + proto.STRING, + number=8, + ) + periodic_tuning_state: PeriodicTuningState = proto.Field( + proto.ENUM, + number=11, + enum=PeriodicTuningState, + ) + last_tune_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=12, + message=timestamp_pb2.Timestamp, + ) + tuning_operation: str = proto.Field( + proto.STRING, + number=15, + ) + data_state: DataState = proto.Field( + proto.ENUM, + number=16, + enum=DataState, + ) + filtering_option: common.RecommendationsFilteringOption = proto.Field( + proto.ENUM, + number=18, + enum=common.RecommendationsFilteringOption, + ) + serving_config_lists: MutableSequence[ServingConfigList] = proto.RepeatedField( + proto.MESSAGE, + number=19, + message=ServingConfigList, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model_service.py new file mode 100644 index 00000000..f80dee8c --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/model_service.py @@ -0,0 +1,274 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import model as gcr_model +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'CreateModelRequest', + 'UpdateModelRequest', + 'GetModelRequest', + 'PauseModelRequest', + 'ResumeModelRequest', + 'ListModelsRequest', + 'DeleteModelRequest', + 'ListModelsResponse', + 'TuneModelRequest', + 'CreateModelMetadata', + 'TuneModelMetadata', + 'TuneModelResponse', + }, +) + + +class CreateModelRequest(proto.Message): + r"""Request for creating a model. + + Attributes: + parent (str): + Required. The parent resource under which to create the + model. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + model (google.cloud.retail_v2beta.types.Model): + Required. The payload of the + [Model][google.cloud.retail.v2beta.Model] to create. + dry_run (bool): + Optional. Whether to run a dry run to + validate the request (without actually creating + the model). + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_model.Model, + ) + dry_run: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class UpdateModelRequest(proto.Message): + r"""Request for updating an existing model. + + Attributes: + model (google.cloud.retail_v2beta.types.Model): + Required. The body of the updated + [Model][google.cloud.retail.v2beta.Model]. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Optional. Indicates which fields in the + provided 'model' to update. If not set, by + default updates all fields. + """ + + model: gcr_model.Model = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class GetModelRequest(proto.Message): + r"""Request for getting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to get. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class PauseModelRequest(proto.Message): + r"""Request for pausing training of a model. + + Attributes: + name (str): + Required. The name of the model to pause. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ResumeModelRequest(proto.Message): + r"""Request for resuming training of a model. + + Attributes: + name (str): + Required. The name of the model to resume. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsRequest(proto.Message): + r"""Request for listing models associated with a resource. + + Attributes: + parent (str): + Required. The parent for which to list models. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 50. Max + allowed value is 1000. + page_token (str): + Optional. A page token, received from a previous + ``ListModels`` call. Provide this to retrieve the subsequent + page. + """ + + 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 DeleteModelRequest(proto.Message): + r"""Request for deleting a model. + + Attributes: + name (str): + Required. The resource name of the + [Model][google.cloud.retail.v2beta.Model] to delete. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListModelsResponse(proto.Message): + r"""Response to a ListModelRequest. + + Attributes: + models (MutableSequence[google.cloud.retail_v2beta.types.Model]): + List of Models. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + models: MutableSequence[gcr_model.Model] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_model.Model, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class TuneModelRequest(proto.Message): + r"""Request to manually start a tuning process now (instead of + waiting for the periodically scheduled tuning to happen). + + Attributes: + name (str): + Required. The resource name of the model to tune. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class CreateModelMetadata(proto.Message): + r"""Metadata associated with a create operation. + + Attributes: + model (str): + The resource name of the model that this create applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelMetadata(proto.Message): + r"""Metadata associated with a tune operation. + + Attributes: + model (str): + The resource name of the model that this tune applies to. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/models/{model_id}`` + """ + + model: str = proto.Field( + proto.STRING, + number=1, + ) + + +class TuneModelResponse(proto.Message): + r"""Response associated with a tune operation. + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/prediction_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/prediction_service.py new file mode 100644 index 00000000..f019804b --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/prediction_service.py @@ -0,0 +1,297 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import user_event as gcr_user_event +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'PredictRequest', + 'PredictResponse', + }, +) + + +class PredictRequest(proto.Message): + r"""Request message for Predict method. + + Attributes: + placement (str): + Required. Full resource name of the format: + ``{placement=projects/*/locations/global/catalogs/default_catalog/servingConfigs/*}`` + or + ``{placement=projects/*/locations/global/catalogs/default_catalog/placements/*}``. + We recommend using the ``servingConfigs`` resource. + ``placements`` is a legacy resource. The ID of the + Recommendations AI serving config or placement. Before you + can request predictions from your model, you must create at + least one serving config or placement for it. For more + information, see [Manage serving configs] + (https://cloud.google.com/retail/docs/manage-configs). + + The full list of available serving configs can be seen at + https://console.cloud.google.com/ai/retail/catalogs/default_catalog/configs + user_event (google.cloud.retail_v2beta.types.UserEvent): + Required. Context about the user, what they are looking at + and what action they took to trigger the predict request. + Note that this user event detail won't be ingested to + userEvent logs. Thus, a separate userEvent write request is + required for event logging. + + Don't set + [UserEvent.visitor_id][google.cloud.retail.v2beta.UserEvent.visitor_id] + or + [UserInfo.user_id][google.cloud.retail.v2beta.UserInfo.user_id] + to the same fixed ID for different users. If you are trying + to receive non-personalized recommendations (not + recommended; this can negatively impact model performance), + instead set + [UserEvent.visitor_id][google.cloud.retail.v2beta.UserEvent.visitor_id] + to a random unique ID and leave + [UserInfo.user_id][google.cloud.retail.v2beta.UserInfo.user_id] + unset. + page_size (int): + Maximum number of results to return. Set this + property to the number of prediction results + needed. If zero, the service will choose a + reasonable default. The maximum allowed value is + 100. Values above 100 will be coerced to 100. + page_token (str): + This field is not used; leave it unset. + filter (str): + Filter for restricting prediction results with a length + limit of 5,000 characters. Accepts values for tags and the + ``filterOutOfStockItems`` flag. + + - Tag expressions. Restricts predictions to products that + match all of the specified tags. Boolean operators ``OR`` + and ``NOT`` are supported if the expression is enclosed + in parentheses, and must be separated from the tag values + by a space. ``-"tagA"`` is also supported and is + equivalent to ``NOT "tagA"``. Tag values must be double + quoted UTF-8 encoded strings with a size limit of 1,000 + characters. + + Note: "Recently viewed" models don't support tag + filtering at the moment. + + - filterOutOfStockItems. Restricts predictions to products + that do not have a stockState value of OUT_OF_STOCK. + + Examples: + + - tag=("Red" OR "Blue") tag="New-Arrival" tag=(NOT + "promotional") + - filterOutOfStockItems tag=(-"promotional") + - filterOutOfStockItems + + If your filter blocks all prediction results, the API will + return *no* results. If instead you want empty result sets + to return generic (unfiltered) popular products, set + ``strictFiltering`` to False in ``PredictRequest.params``. + Note that the API will never return items with storageStatus + of "EXPIRED" or "DELETED" regardless of filter choices. + + If ``filterSyntaxV2`` is set to true under the ``params`` + field, then attribute-based expressions are expected instead + of the above described tag-based syntax. Examples: + + - (colors: ANY("Red", "Blue")) AND NOT (categories: + ANY("Phones")) + - (availability: ANY("IN_STOCK")) AND (colors: ANY("Red") + OR categories: ANY("Phones")) + + For more information, see `Filter + recommendations `__. + validate_only (bool): + Use validate only mode for this prediction + query. If set to true, a dummy model will be + used that returns arbitrary products. Note that + the validate only mode should only be used for + testing the API, or if the model is not ready. + params (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Additional domain specific parameters for the predictions. + + Allowed values: + + - ``returnProduct``: Boolean. If set to true, the + associated product object will be returned in the + ``results.metadata`` field in the prediction response. + - ``returnScore``: Boolean. If set to true, the prediction + 'score' corresponding to each returned product will be + set in the ``results.metadata`` field in the prediction + response. The given 'score' indicates the probability of + a product being clicked/purchased given the user's + context and history. + - ``strictFiltering``: Boolean. True by default. If set to + false, the service will return generic (unfiltered) + popular products instead of empty if your filter blocks + all prediction results. + - ``priceRerankLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of + {'no-price-reranking', 'low-price-reranking', + 'medium-price-reranking', 'high-price-reranking'}. This + gives request-level control and adjusts prediction + results based on product price. + - ``diversityLevel``: String. Default empty. If set to be + non-empty, then it needs to be one of {'no-diversity', + 'low-diversity', 'medium-diversity', 'high-diversity', + 'auto-diversity'}. This gives request-level control and + adjusts prediction results based on product category. + - ``filterSyntaxV2``: Boolean. False by default. If set to + true, the ``filter`` field is interpreteted according to + the new, attribute-based syntax. + labels (MutableMapping[str, str]): + The labels applied to a resource must meet the following + requirements: + + - Each resource can have multiple labels, up to a maximum + of 64. + - Each label must be a key-value pair. + - Keys have a minimum length of 1 character and a maximum + length of 63 characters and cannot be empty. Values can + be empty and have a maximum length of 63 characters. + - Keys and values can contain only lowercase letters, + numeric characters, underscores, and dashes. All + characters must use UTF-8 encoding, and international + characters are allowed. + - The key portion of a label must be unique. However, you + can use the same key with multiple resources. + - Keys must start with a lowercase letter or international + character. + + See `Google Cloud + Document `__ + for more details. + """ + + placement: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: gcr_user_event.UserEvent = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) + page_size: int = proto.Field( + proto.INT32, + number=3, + ) + page_token: str = proto.Field( + proto.STRING, + number=4, + ) + filter: str = proto.Field( + proto.STRING, + number=5, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=6, + ) + params: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=struct_pb2.Value, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=8, + ) + + +class PredictResponse(proto.Message): + r"""Response message for predict method. + + Attributes: + results (MutableSequence[google.cloud.retail_v2beta.types.PredictResponse.PredictionResult]): + A list of recommended products. The order + represents the ranking (from the most relevant + product to the least). + attribution_token (str): + A unique attribution token. This should be included in the + [UserEvent][google.cloud.retail.v2beta.UserEvent] logs + resulting from this recommendation, which enables accurate + attribution of recommendation model performance. + missing_ids (MutableSequence[str]): + IDs of products in the request that were + missing from the inventory. + validate_only (bool): + True if the validateOnly property was set in + the request. + """ + + class PredictionResult(proto.Message): + r"""PredictionResult represents the recommendation prediction + results. + + Attributes: + id (str): + ID of the recommended product + metadata (MutableMapping[str, google.protobuf.struct_pb2.Value]): + Additional product metadata / annotations. + + Possible values: + + - ``product``: JSON representation of the product. Is set + if ``returnProduct`` is set to true in + ``PredictRequest.params``. + - ``score``: Prediction score in double value. Is set if + ``returnScore`` is set to true in + ``PredictRequest.params``. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + metadata: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=2, + message=struct_pb2.Value, + ) + + results: MutableSequence[PredictionResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=PredictionResult, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=2, + ) + missing_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + validate_only: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product.py new file mode 100644 index 00000000..8d33822b --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product.py @@ -0,0 +1,800 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import promotion +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'Product', + }, +) + + +class Product(proto.Message): + r"""Product captures all metadata information of items to be + recommended or searched. + + 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: + expire_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this product becomes unavailable for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search]. + Note that this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT]. + In general, we suggest the users to delete the stale + products explicitly, instead of using this field to + determine staleness. + + If it is set, the + [Product][google.cloud.retail.v2beta.Product] is not + available for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + after + [expire_time][google.cloud.retail.v2beta.Product.expire_time]. + However, the product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + [expire_time][google.cloud.retail.v2beta.Product.expire_time] + must be later than + [available_time][google.cloud.retail.v2beta.Product.available_time] + and + [publish_time][google.cloud.retail.v2beta.Product.publish_time], + otherwise an INVALID_ARGUMENT error is thrown. + + Corresponding properties: Google Merchant Center property + `expiration_date `__. + + This field is a member of `oneof`_ ``expiration``. + ttl (google.protobuf.duration_pb2.Duration): + Input only. The TTL (time to live) of the product. Note that + this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT]. + In general, we suggest the users to delete the stale + products explicitly, instead of using this field to + determine staleness. + + If it is set, it must be a non-negative value, and + [expire_time][google.cloud.retail.v2beta.Product.expire_time] + is set as current timestamp plus + [ttl][google.cloud.retail.v2beta.Product.ttl]. The derived + [expire_time][google.cloud.retail.v2beta.Product.expire_time] + is returned in the output and + [ttl][google.cloud.retail.v2beta.Product.ttl] is left blank + when retrieving the + [Product][google.cloud.retail.v2beta.Product]. + + If it is set, the product is not available for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + after current timestamp plus + [ttl][google.cloud.retail.v2beta.Product.ttl]. However, the + product can still be retrieved by + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + and + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts]. + + This field is a member of `oneof`_ ``expiration``. + name (str): + Immutable. Full resource name of the product, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/product_id``. + id (str): + Immutable. [Product][google.cloud.retail.v2beta.Product] + identifier, which is the final component of + [name][google.cloud.retail.v2beta.Product.name]. For + example, this field is "id_1", if + [name][google.cloud.retail.v2beta.Product.name] is + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/id_1``. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `id `__. + Schema.org property + `Product.sku `__. + type_ (google.cloud.retail_v2beta.types.Product.Type): + Immutable. The type of the product. Default to + [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2beta.ProductLevelConfig.ingestion_product_type] + if unset. + primary_product_id (str): + Variant group identifier. Must be an + [id][google.cloud.retail.v2beta.Product.id], with the same + parent branch with this product. Otherwise, an error is + thrown. + + For + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]s, this field + can only be empty or set to the same value as + [id][google.cloud.retail.v2beta.Product.id]. + + For VARIANT [Product][google.cloud.retail.v2beta.Product]s, + this field cannot be empty. A maximum of 2,000 products are + allowed to share the same + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]. Otherwise, an + INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `item_group_id `__. + Schema.org property + `Product.inProductGroupWithID `__. + collection_member_ids (MutableSequence[str]): + The [id][google.cloud.retail.v2beta.Product.id] of the + collection members when + [type][google.cloud.retail.v2beta.Product.type] is + [Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION]. + + Non-existent product ids are allowed. The + [type][google.cloud.retail.v2beta.Product.type] of the + members must be either + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + or + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + otherwise an INVALID_ARGUMENT error is thrown. Should not + set it for other types. A maximum of 1000 values are + allowed. Otherwise, an INVALID_ARGUMENT error is return. + gtin (str): + The Global Trade Item Number (GTIN) of the product. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + This field must be a Unigram. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `gtin `__. + Schema.org property + `Product.isbn `__, + `Product.gtin8 `__, + `Product.gtin12 `__, + `Product.gtin13 `__, or + `Product.gtin14 `__. + + If the value is not a valid GTIN, an INVALID_ARGUMENT error + is returned. + categories (MutableSequence[str]): + Product categories. This field is repeated for supporting + one product belonging to several parallel categories. + Strongly recommended using the full path for better search / + recommendation quality. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + For example, if a shoes product belongs to both ["Shoes & + Accessories" -> "Shoes"] and ["Sports & Fitness" -> + "Athletic Clothing" -> "Shoes"], it could be represented as: + + :: + + "categories": [ + "Shoes & Accessories > Shoes", + "Sports & Fitness > Athletic Clothing > Shoes" + ] + + Must be set for + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product] otherwise an + INVALID_ARGUMENT error is returned. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2beta.Product]. Empty values + are not allowed. Each value must be a UTF-8 encoded string + with a length limit of 5,000 characters. Otherwise, an + INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `google_product_category `__. + Schema.org property [Product.category] + (https://schema.org/category). + title (str): + Required. Product title. + + This field must be a UTF-8 encoded string with a length + limit of 1,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `title `__. + Schema.org property + `Product.name `__. + brands (MutableSequence[str]): + The brands of the product. + + A maximum of 30 brands are allowed. Each brand must be a + UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `brand `__. + Schema.org property + `Product.brand `__. + description (str): + Product description. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `description `__. + Schema.org property + `Product.description `__. + language_code (str): + Language of the title/description and other string + attributes. Use language tags defined by `BCP + 47 `__. + + For product prediction, this field is ignored and the model + automatically detects the text language. The + [Product][google.cloud.retail.v2beta.Product] can include + text in different languages, but duplicating + [Product][google.cloud.retail.v2beta.Product]s to provide + text in multiple languages can result in degraded model + performance. + + For product search this field is in use. It defaults to + "en-US" if unset. + attributes (MutableMapping[str, google.cloud.retail_v2beta.types.CustomAttribute]): + Highly encouraged. Extra product attributes to be included. + For example, for products, this could include the store + name, vendor, style, color, etc. These are very strong + signals for recommendation model, thus we highly recommend + providing the attributes here. + + Features that can take on one of a limited number of + possible values. Two types of features can be set are: + + Textual features. some examples would be the brand/maker of + a product, or country of a customer. Numerical features. + Some examples would be the height/weight of a product, or + age of a customer. + + For example: + ``{ "vendor": {"text": ["vendor123", "vendor456"]}, "lengths_cm": {"numbers":[2.3, 15.4]}, "heights_cm": {"numbers":[8.1, 6.4]} }``. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - Max entries count: 200. + - The key must be a UTF-8 encoded string with a length + limit of 128 characters. + - For indexable attribute, the key must match the pattern: + ``[a-zA-Z0-9][a-zA-Z0-9_]*``. For example, + ``key0LikeThis`` or ``KEY_1_LIKE_THIS``. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a + non-empty UTF-8 encoded string with a length limit of 256 + characters. + - For number attributes, at most 400 values are allowed. + tags (MutableSequence[str]): + Custom tags associated with the product. + + At most 250 values are allowed per + [Product][google.cloud.retail.v2beta.Product]. This value + must be a UTF-8 encoded string with a length limit of 1,000 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This tag can be used for filtering recommendation results by + passing the tag as part of the + [PredictRequest.filter][google.cloud.retail.v2beta.PredictRequest.filter]. + + Corresponding properties: Google Merchant Center property + `custom_label_0–4 `__. + price_info (google.cloud.retail_v2beta.types.PriceInfo): + Product price and cost information. + + Corresponding properties: Google Merchant Center property + `price `__. + rating (google.cloud.retail_v2beta.types.Rating): + The rating of this product. + available_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when this + [Product][google.cloud.retail.v2beta.Product] becomes + available for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search]. + Note that this is only applicable to + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION], + and ignored for + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT]. + availability (google.cloud.retail_v2beta.types.Product.Availability): + The online availability of the + [Product][google.cloud.retail.v2beta.Product]. Default to + [Availability.IN_STOCK][google.cloud.retail.v2beta.Product.Availability.IN_STOCK]. + + Corresponding properties: Google Merchant Center property + `availability `__. + Schema.org property + `Offer.availability `__. + available_quantity (google.protobuf.wrappers_pb2.Int32Value): + The available quantity of the item. + fulfillment_info (MutableSequence[google.cloud.retail_v2beta.types.FulfillmentInfo]): + Fulfillment information, such as the store IDs for in-store + pickup or region IDs for different shipping methods. + + All the elements must have distinct + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type]. + Otherwise, an INVALID_ARGUMENT error is returned. + uri (str): + Canonical URL directly linking to the product detail page. + + It is strongly recommended to provide a valid uri for the + product, otherwise the service performance could be + significantly degraded. + + This field must be a UTF-8 encoded string with a length + limit of 5,000 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + + Corresponding properties: Google Merchant Center property + `link `__. + Schema.org property `Offer.url `__. + images (MutableSequence[google.cloud.retail_v2beta.types.Image]): + Product images for the product. We highly recommend putting + the main image first. + + A maximum of 300 images are allowed. + + Corresponding properties: Google Merchant Center property + `image_link `__. + Schema.org property + `Product.image `__. + audience (google.cloud.retail_v2beta.types.Audience): + The target group associated with a given + audience (e.g. male, veterans, car owners, + musicians, etc.) of the product. + color_info (google.cloud.retail_v2beta.types.ColorInfo): + The color of the product. + + Corresponding properties: Google Merchant Center property + `color `__. + Schema.org property + `Product.color `__. + sizes (MutableSequence[str]): + The size of the product. To represent different size systems + or size types, consider using this format: + [[[size_system:]size_type:]size_value]. + + For example, in "US:MENS:M", "US" represents size system; + "MENS" represents size type; "M" represents size value. In + "GIRLS:27", size system is empty; "GIRLS" represents size + type; "27" represents size value. In "32 inches", both size + system and size type are empty, while size value is "32 + inches". + + A maximum of 20 values are allowed per + [Product][google.cloud.retail.v2beta.Product]. Each value + must be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `size `__, + `size_type `__, + and + `size_system `__. + Schema.org property + `Product.size `__. + materials (MutableSequence[str]): + The material of the product. For example, "leather", + "wooden". + + A maximum of 20 values are allowed. Each value must be a + UTF-8 encoded string with a length limit of 200 characters. + Otherwise, an INVALID_ARGUMENT error is returned. + + Corresponding properties: Google Merchant Center property + `material `__. + Schema.org property + `Product.material `__. + patterns (MutableSequence[str]): + The pattern or graphic print of the product. For example, + "striped", "polka dot", "paisley". + + A maximum of 20 values are allowed per + [Product][google.cloud.retail.v2beta.Product]. Each value + must be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `pattern `__. + Schema.org property + `Product.pattern `__. + conditions (MutableSequence[str]): + The condition of the product. Strongly encouraged to use the + standard values: "new", "refurbished", "used". + + A maximum of 1 value is allowed per + [Product][google.cloud.retail.v2beta.Product]. Each value + must be a UTF-8 encoded string with a length limit of 128 + characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + Corresponding properties: Google Merchant Center property + `condition `__. + Schema.org property + `Offer.itemCondition `__. + promotions (MutableSequence[google.cloud.retail_v2beta.types.Promotion]): + The promotions applied to the product. A maximum of 10 + values are allowed per + [Product][google.cloud.retail.v2beta.Product]. Only + [Promotion.promotion_id][google.cloud.retail.v2beta.Promotion.promotion_id] + will be used, other fields will be ignored if set. + publish_time (google.protobuf.timestamp_pb2.Timestamp): + The timestamp when the product is published by the retailer + for the first time, which indicates the freshness of the + products. Note that this field is different from + [available_time][google.cloud.retail.v2beta.Product.available_time], + given it purely describes product freshness regardless of + when it is available on search and recommendation. + retrievable_fields (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the + [Product][google.cloud.retail.v2beta.Product]s are returned + in + [SearchResponse][google.cloud.retail.v2beta.SearchResponse]. + + Supported fields for all + [type][google.cloud.retail.v2beta.Product.type]s: + + - [audience][google.cloud.retail.v2beta.Product.audience] + - [availability][google.cloud.retail.v2beta.Product.availability] + - [brands][google.cloud.retail.v2beta.Product.brands] + - [color_info][google.cloud.retail.v2beta.Product.color_info] + - [conditions][google.cloud.retail.v2beta.Product.conditions] + - [gtin][google.cloud.retail.v2beta.Product.gtin] + - [materials][google.cloud.retail.v2beta.Product.materials] + - [name][google.cloud.retail.v2beta.Product.name] + - [patterns][google.cloud.retail.v2beta.Product.patterns] + - [price_info][google.cloud.retail.v2beta.Product.price_info] + - [rating][google.cloud.retail.v2beta.Product.rating] + - [sizes][google.cloud.retail.v2beta.Product.sizes] + - [title][google.cloud.retail.v2beta.Product.title] + - [uri][google.cloud.retail.v2beta.Product.uri] + + Supported fields only for + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION]: + + - [categories][google.cloud.retail.v2beta.Product.categories] + - [description][google.cloud.retail.v2beta.Product.description] + - [images][google.cloud.retail.v2beta.Product.images] + + Supported fields only for + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT]: + + - Only the first image in + [images][google.cloud.retail.v2beta.Product.images] + + To mark + [attributes][google.cloud.retail.v2beta.Product.attributes] + as retrievable, include paths of the form "attributes.key" + where "key" is the key of a custom attribute, as specified + in + [attributes][google.cloud.retail.v2beta.Product.attributes]. + + For + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + and + [Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION], + the following fields are always returned in + [SearchResponse][google.cloud.retail.v2beta.SearchResponse] + by default: + + - [name][google.cloud.retail.v2beta.Product.name] + + For + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT], + the following fields are always returned in by default: + + - [name][google.cloud.retail.v2beta.Product.name] + - [color_info][google.cloud.retail.v2beta.Product.color_info] + + The maximum number of paths is 30. Otherwise, an + INVALID_ARGUMENT error is returned. + + Note: Returning more fields in + [SearchResponse][google.cloud.retail.v2beta.SearchResponse] + can increase response payload size and serving latency. + + This field is deprecated. Use the retrievable site-wide + control instead. + variants (MutableSequence[google.cloud.retail_v2beta.types.Product]): + Output only. Product variants grouped together on primary + product which share similar product attributes. It's + automatically grouped by + [primary_product_id][google.cloud.retail.v2beta.Product.primary_product_id] + for all the product variants. Only populated for + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]s. + + Note: This field is OUTPUT_ONLY for + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct]. + Do not set this field in API requests. + local_inventories (MutableSequence[google.cloud.retail_v2beta.types.LocalInventory]): + Output only. A list of local inventories specific to + different places. + + This field can be managed by + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + and + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + APIs if fine-grained, high-volume updates are necessary. + """ + class Type(proto.Enum): + r"""The type of this product. + + Values: + TYPE_UNSPECIFIED (0): + Default value. Default to + [Catalog.product_level_config.ingestion_product_type][google.cloud.retail.v2beta.ProductLevelConfig.ingestion_product_type] + if unset. + PRIMARY (1): + The primary type. + + As the primary unit for predicting, indexing and search + serving, a + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product] is grouped + with multiple + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s. + VARIANT (2): + The variant type. + + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s usually share + some common attributes on the same + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]s, but they + have variant attributes like different colors, sizes and + prices, etc. + COLLECTION (3): + The collection type. Collection products are bundled + [Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]s or + [Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s that are sold + together, such as a jewelry set with necklaces, earrings and + rings, etc. + """ + TYPE_UNSPECIFIED = 0 + PRIMARY = 1 + VARIANT = 2 + COLLECTION = 3 + + class Availability(proto.Enum): + r"""Product availability. If this field is unspecified, the + product is assumed to be in stock. + + Values: + AVAILABILITY_UNSPECIFIED (0): + Default product availability. Default to + [Availability.IN_STOCK][google.cloud.retail.v2beta.Product.Availability.IN_STOCK] + if unset. + IN_STOCK (1): + Product in stock. + OUT_OF_STOCK (2): + Product out of stock. + PREORDER (3): + Product that is in pre-order state. + BACKORDER (4): + Product that is back-ordered (i.e. + temporarily out of stock). + """ + AVAILABILITY_UNSPECIFIED = 0 + IN_STOCK = 1 + OUT_OF_STOCK = 2 + PREORDER = 3 + BACKORDER = 4 + + expire_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=16, + oneof='expiration', + message=timestamp_pb2.Timestamp, + ) + ttl: duration_pb2.Duration = proto.Field( + proto.MESSAGE, + number=17, + oneof='expiration', + message=duration_pb2.Duration, + ) + name: str = proto.Field( + proto.STRING, + number=1, + ) + id: str = proto.Field( + proto.STRING, + number=2, + ) + type_: Type = proto.Field( + proto.ENUM, + number=3, + enum=Type, + ) + primary_product_id: str = proto.Field( + proto.STRING, + number=4, + ) + collection_member_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + gtin: str = proto.Field( + proto.STRING, + number=6, + ) + categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + title: str = proto.Field( + proto.STRING, + number=8, + ) + brands: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + description: str = proto.Field( + proto.STRING, + number=10, + ) + language_code: str = proto.Field( + proto.STRING, + number=11, + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=12, + message=common.CustomAttribute, + ) + tags: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + price_info: common.PriceInfo = proto.Field( + proto.MESSAGE, + number=14, + message=common.PriceInfo, + ) + rating: common.Rating = proto.Field( + proto.MESSAGE, + number=15, + message=common.Rating, + ) + available_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=18, + message=timestamp_pb2.Timestamp, + ) + availability: Availability = proto.Field( + proto.ENUM, + number=19, + enum=Availability, + ) + available_quantity: wrappers_pb2.Int32Value = proto.Field( + proto.MESSAGE, + number=20, + message=wrappers_pb2.Int32Value, + ) + fulfillment_info: MutableSequence[common.FulfillmentInfo] = proto.RepeatedField( + proto.MESSAGE, + number=21, + message=common.FulfillmentInfo, + ) + uri: str = proto.Field( + proto.STRING, + number=22, + ) + images: MutableSequence[common.Image] = proto.RepeatedField( + proto.MESSAGE, + number=23, + message=common.Image, + ) + audience: common.Audience = proto.Field( + proto.MESSAGE, + number=24, + message=common.Audience, + ) + color_info: common.ColorInfo = proto.Field( + proto.MESSAGE, + number=25, + message=common.ColorInfo, + ) + sizes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=26, + ) + materials: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=27, + ) + patterns: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=28, + ) + conditions: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=29, + ) + promotions: MutableSequence[promotion.Promotion] = proto.RepeatedField( + proto.MESSAGE, + number=34, + message=promotion.Promotion, + ) + publish_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=33, + message=timestamp_pb2.Timestamp, + ) + retrievable_fields: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=30, + message=field_mask_pb2.FieldMask, + ) + variants: MutableSequence['Product'] = proto.RepeatedField( + proto.MESSAGE, + number=31, + message='Product', + ) + local_inventories: MutableSequence[common.LocalInventory] = proto.RepeatedField( + proto.MESSAGE, + number=35, + message=common.LocalInventory, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product_service.py new file mode 100644 index 00000000..acf2c875 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/product_service.py @@ -0,0 +1,892 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import product as gcr_product +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'CreateProductRequest', + 'GetProductRequest', + 'UpdateProductRequest', + 'DeleteProductRequest', + 'ListProductsRequest', + 'ListProductsResponse', + 'SetInventoryRequest', + 'SetInventoryMetadata', + 'SetInventoryResponse', + 'AddFulfillmentPlacesRequest', + 'AddFulfillmentPlacesMetadata', + 'AddFulfillmentPlacesResponse', + 'AddLocalInventoriesRequest', + 'AddLocalInventoriesMetadata', + 'AddLocalInventoriesResponse', + 'RemoveLocalInventoriesRequest', + 'RemoveLocalInventoriesMetadata', + 'RemoveLocalInventoriesResponse', + 'RemoveFulfillmentPlacesRequest', + 'RemoveFulfillmentPlacesMetadata', + 'RemoveFulfillmentPlacesResponse', + }, +) + + +class CreateProductRequest(proto.Message): + r"""Request message for + [ProductService.CreateProduct][google.cloud.retail.v2beta.ProductService.CreateProduct] + method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch``. + product (google.cloud.retail_v2beta.types.Product): + Required. The [Product][google.cloud.retail.v2beta.Product] + to create. + product_id (str): + Required. The ID to use for the + [Product][google.cloud.retail.v2beta.Product], which will + become the final component of the + [Product.name][google.cloud.retail.v2beta.Product.name]. + + If the caller does not have permission to create the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + This field must be unique among all + [Product][google.cloud.retail.v2beta.Product]s with the same + [parent][google.cloud.retail.v2beta.CreateProductRequest.parent]. + Otherwise, an ALREADY_EXISTS error is returned. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + product_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class GetProductRequest(proto.Message): + r"""Request message for + [ProductService.GetProduct][google.cloud.retail.v2beta.ProductService.GetProduct] + method. + + Attributes: + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the requested + [Product][google.cloud.retail.v2beta.Product] does not + exist, a NOT_FOUND error is returned. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class UpdateProductRequest(proto.Message): + r"""Request message for + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + method. + + Attributes: + product (google.cloud.retail_v2beta.types.Product): + Required. The product to update/create. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + update does not exist and + [allow_missing][google.cloud.retail.v2beta.UpdateProductRequest.allow_missing] + is not set, a NOT_FOUND error is returned. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [Product][google.cloud.retail.v2beta.Product] to update. The + immutable and output only fields are NOT supported. If not + set, all supported fields (the fields that are neither + immutable nor output only) are updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + + The attribute key can be updated by setting the mask path as + "attributes.${key_name}". If a key name is present in the + mask but not in the patching product from the request, this + key will be deleted after the update. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2beta.Product] is not found, + a new [Product][google.cloud.retail.v2beta.Product] will be + created. In this situation, ``update_mask`` is ignored. + """ + + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class DeleteProductRequest(proto.Message): + r"""Request message for + [ProductService.DeleteProduct][google.cloud.retail.v2beta.ProductService.DeleteProduct] + method. + + Attributes: + name (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to delete the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + delete does not exist, a NOT_FOUND error is returned. + + The [Product][google.cloud.retail.v2beta.Product] to delete + can neither be a + [Product.Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2beta.Product] member nor a + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product] with more than + one + [variants][google.cloud.retail.v2beta.Product.Type.VARIANT]. + Otherwise, an INVALID_ARGUMENT error is returned. + + All inventory information for the named + [Product][google.cloud.retail.v2beta.Product] will be + deleted. + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListProductsRequest(proto.Message): + r"""Request message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + method. + + Attributes: + parent (str): + Required. The parent branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + Use ``default_branch`` as the branch ID, to list products + under the default branch. + + If the caller does not have permission to list + [Product][google.cloud.retail.v2beta.Product]s under this + branch, regardless of whether or not this branch exists, a + PERMISSION_DENIED error is returned. + page_size (int): + Maximum number of + [Product][google.cloud.retail.v2beta.Product]s to return. If + unspecified, defaults to 100. The maximum allowed value is + 1000. Values above 1000 will be coerced to 1000. + + If this field is negative, an INVALID_ARGUMENT error is + returned. + page_token (str): + A page token + [ListProductsResponse.next_page_token][google.cloud.retail.v2beta.ListProductsResponse.next_page_token], + received from a previous + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + filter (str): + A filter to apply on the list results. Supported features: + + - List all the products under the parent branch if + [filter][google.cloud.retail.v2beta.ListProductsRequest.filter] + is unset. + - List + [Product.Type.VARIANT][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s sharing + the same + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product]. For + example: ``primary_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2beta.Product]s + bundled in a + [Product.Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2beta.Product]. For + example: ``collection_product_id = "some_product_id"`` + - List [Product][google.cloud.retail.v2beta.Product]s with + a partibular type. For example: ``type = "PRIMARY"`` + ``type = "VARIANT"`` ``type = "COLLECTION"`` + + If the field is unrecognizable, an INVALID_ARGUMENT error is + returned. + + If the specified + [Product.Type.PRIMARY][google.cloud.retail.v2beta.Product.Type.PRIMARY] + [Product][google.cloud.retail.v2beta.Product] or + [Product.Type.COLLECTION][google.cloud.retail.v2beta.Product.Type.COLLECTION] + [Product][google.cloud.retail.v2beta.Product] does not + exist, a NOT_FOUND error is returned. + read_mask (google.protobuf.field_mask_pb2.FieldMask): + The fields of [Product][google.cloud.retail.v2beta.Product] + to return in the responses. If not set or empty, the + following fields are returned: + + - [Product.name][google.cloud.retail.v2beta.Product.name] + - [Product.id][google.cloud.retail.v2beta.Product.id] + - [Product.title][google.cloud.retail.v2beta.Product.title] + - [Product.uri][google.cloud.retail.v2beta.Product.uri] + - [Product.images][google.cloud.retail.v2beta.Product.images] + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + - [Product.brands][google.cloud.retail.v2beta.Product.brands] + + If "*" is provided, all fields are returned. + [Product.name][google.cloud.retail.v2beta.Product.name] is + always returned no matter what mask is set. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned. + """ + + 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, + ) + filter: str = proto.Field( + proto.STRING, + number=4, + ) + read_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=5, + message=field_mask_pb2.FieldMask, + ) + + +class ListProductsResponse(proto.Message): + r"""Response message for + [ProductService.ListProducts][google.cloud.retail.v2beta.ProductService.ListProducts] + method. + + Attributes: + products (MutableSequence[google.cloud.retail_v2beta.types.Product]): + The [Product][google.cloud.retail.v2beta.Product]s. + next_page_token (str): + A token that can be sent as + [ListProductsRequest.page_token][google.cloud.retail.v2beta.ListProductsRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + """ + + @property + def raw_page(self): + return self + + products: MutableSequence[gcr_product.Product] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class SetInventoryRequest(proto.Message): + r"""Request message for + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + method. + + Attributes: + inventory (google.cloud.retail_v2beta.types.Product): + Required. The inventory information to update. The allowable + fields to update are: + + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + - [Product.availability][google.cloud.retail.v2beta.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2beta.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + The updated inventory fields must be specified in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask]. + + If + [SetInventoryRequest.inventory.name][google.cloud.retail.v2beta.Product.name] + is empty or invalid, an INVALID_ARGUMENT error is returned. + + If the caller does not have permission to update the + [Product][google.cloud.retail.v2beta.Product] named in + [Product.name][google.cloud.retail.v2beta.Product.name], + regardless of whether or not it exists, a PERMISSION_DENIED + error is returned. + + If the [Product][google.cloud.retail.v2beta.Product] to + update does not have existing inventory information, the + provided inventory information will be inserted. + + If the [Product][google.cloud.retail.v2beta.Product] to + update has existing inventory information, the provided + inventory information will be merged while respecting the + last update time for each inventory field, using the + provided or default value for + [SetInventoryRequest.set_time][google.cloud.retail.v2beta.SetInventoryRequest.set_time]. + + The caller can replace place IDs for a subset of fulfillment + types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types and + corresponding place IDs to update in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + + The caller can clear all place IDs from a subset of + fulfillment types in the following ways: + + - Adds "fulfillment_info" in + [SetInventoryRequest.set_mask][google.cloud.retail.v2beta.SetInventoryRequest.set_mask] + - Specifies only the desired fulfillment types to clear in + [SetInventoryRequest.inventory.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + - Checks that only the desired fulfillment info types have + empty + [SetInventoryRequest.inventory.fulfillment_info.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + + The last update time is recorded for the following inventory + fields: + + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + - [Product.availability][google.cloud.retail.v2beta.Product.availability] + - [Product.available_quantity][google.cloud.retail.v2beta.Product.available_quantity] + - [Product.fulfillment_info][google.cloud.retail.v2beta.Product.fulfillment_info] + + If a full overwrite of inventory information while ignoring + timestamps is needed, + [ProductService.UpdateProduct][google.cloud.retail.v2beta.ProductService.UpdateProduct] + should be invoked instead. + set_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided + [Product][google.cloud.retail.v2beta.Product] to update. + + At least one field must be provided. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + set_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the request is issued, used to + prevent out-of-order updates on inventory fields + with the last update time recorded. If not + provided, the internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2beta.Product] with name + [Product.name][google.cloud.retail.v2beta.Product.name] is + not found, the inventory update will still be processed and + retained for at most 1 day until the + [Product][google.cloud.retail.v2beta.Product] is created. If + set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2beta.Product] is not found. + """ + + inventory: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + set_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + set_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=4, + ) + + +class SetInventoryMetadata(proto.Message): + r"""Metadata related to the progress of the SetInventory operation. + Currently empty because there is no meaningful metadata populated + from the + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + method. + + """ + + +class SetInventoryResponse(proto.Message): + r"""Response of the SetInventoryRequest. Currently empty because there + is no meaningful response populated from the + [ProductService.SetInventory][google.cloud.retail.v2beta.ProductService.SetInventory] + method. + + """ + + +class AddFulfillmentPlacesRequest(proto.Message): + r"""Request message for + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + This field directly corresponds to + [Product.fulfillment_info.type][google.cloud.retail.v2beta.FulfillmentInfo.type]. + place_ids (MutableSequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2beta.AddFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery" to be added for this + [type][google.cloud.retail.v2beta.AddFulfillmentPlacesRequest.type]. + Duplicate IDs will be automatically ignored. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + + If the total number of place IDs exceeds 2000 for this + [type][google.cloud.retail.v2beta.AddFulfillmentPlacesRequest.type] + after adding, then the update will be rejected. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2beta.Product] is not found, + the fulfillment information will still be processed and + retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2beta.Product] is created. If + set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2beta.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + type_: str = proto.Field( + proto.STRING, + number=2, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + add_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class AddFulfillmentPlacesMetadata(proto.Message): + r"""Metadata related to the progress of the AddFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + method. + + """ + + +class AddFulfillmentPlacesResponse(proto.Message): + r"""Response of the AddFulfillmentPlacesRequest. Currently empty because + there is no meaningful response populated from the + [ProductService.AddFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces] + method. + + """ + + +class AddLocalInventoriesRequest(proto.Message): + r"""Request message for + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + local_inventories (MutableSequence[google.cloud.retail_v2beta.types.LocalInventory]): + Required. A list of inventory information at + difference places. Each place is identified by + its place ID. At most 3000 inventories are + allowed per request. + add_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which inventory fields in the provided list of + [LocalInventory][google.cloud.retail.v2beta.LocalInventory] + to update. The field is updated to the provided value. + + If a field is set while the place does not have a previous + local inventory, the local inventory at that store is + created. + + If a field is set while the value of that field is not + provided, the original field value, if it exists, is + deleted. + + If the mask is not set or set with empty paths, all + inventory fields will be updated. + + If an unsupported or unknown field is provided, an + INVALID_ARGUMENT error is returned and the entire update + will be ignored. + add_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory updates are + issued. Used to prevent out-of-order updates on + local inventory fields. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2beta.Product] is not found, + the local inventory will still be processed and retained for + at most 1 day and processed once the + [Product][google.cloud.retail.v2beta.Product] is created. If + set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2beta.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + local_inventories: MutableSequence[common.LocalInventory] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.LocalInventory, + ) + add_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + add_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=6, + ) + + +class AddLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the AddLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method. + + """ + + +class AddLocalInventoriesResponse(proto.Message): + r"""Response of the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + API. Currently empty because there is no meaningful response + populated from the + [ProductService.AddLocalInventories][google.cloud.retail.v2beta.ProductService.AddLocalInventories] + method. + + """ + + +class RemoveLocalInventoriesRequest(proto.Message): + r"""Request message for + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + place_ids (MutableSequence[str]): + Required. A list of place IDs to have their + inventory deleted. At most 3000 place IDs are + allowed per request. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the inventory deletions are + issued. Used to prevent out-of-order updates and + deletions on local inventory fields. If not + provided, the internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2beta.Product] is not found, + the local inventory removal request will still be processed + and retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2beta.Product] is created. If + set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2beta.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=2, + ) + remove_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=5, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class RemoveLocalInventoriesMetadata(proto.Message): + r"""Metadata related to the progress of the RemoveLocalInventories + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method. + + """ + + +class RemoveLocalInventoriesResponse(proto.Message): + r"""Response of the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + API. Currently empty because there is no meaningful response + populated from the + [ProductService.RemoveLocalInventories][google.cloud.retail.v2beta.ProductService.RemoveLocalInventories] + method. + + """ + + +class RemoveFulfillmentPlacesRequest(proto.Message): + r"""Request message for + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + method. + + Attributes: + product (str): + Required. Full resource name of + [Product][google.cloud.retail.v2beta.Product], such as + ``projects/*/locations/global/catalogs/default_catalog/branches/default_branch/products/some_product_id``. + + If the caller does not have permission to access the + [Product][google.cloud.retail.v2beta.Product], regardless of + whether or not it exists, a PERMISSION_DENIED error is + returned. + type_ (str): + Required. The fulfillment type, including commonly used + types (such as pickup in store and same day delivery), and + custom types. + + Supported values: + + - "pickup-in-store" + - "ship-to-store" + - "same-day-delivery" + - "next-day-delivery" + - "custom-type-1" + - "custom-type-2" + - "custom-type-3" + - "custom-type-4" + - "custom-type-5" + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + + This field directly corresponds to + [Product.fulfillment_info.type][google.cloud.retail.v2beta.FulfillmentInfo.type]. + place_ids (MutableSequence[str]): + Required. The IDs for this + [type][google.cloud.retail.v2beta.RemoveFulfillmentPlacesRequest.type], + such as the store IDs for "pickup-in-store" or the region + IDs for "same-day-delivery", to be removed for this + [type][google.cloud.retail.v2beta.RemoveFulfillmentPlacesRequest.type]. + + At least 1 value is required, and a maximum of 2000 values + are allowed. Each value must be a string with a length limit + of 10 characters, matching the pattern ``[a-zA-Z0-9_-]+``, + such as "store1" or "REGION-2". Otherwise, an + INVALID_ARGUMENT error is returned. + remove_time (google.protobuf.timestamp_pb2.Timestamp): + The time when the fulfillment updates are + issued, used to prevent out-of-order updates on + fulfillment information. If not provided, the + internal system time will be used. + allow_missing (bool): + If set to true, and the + [Product][google.cloud.retail.v2beta.Product] is not found, + the fulfillment information will still be processed and + retained for at most 1 day and processed once the + [Product][google.cloud.retail.v2beta.Product] is created. If + set to false, a NOT_FOUND error is returned if the + [Product][google.cloud.retail.v2beta.Product] is not found. + """ + + product: str = proto.Field( + proto.STRING, + number=1, + ) + type_: str = proto.Field( + proto.STRING, + number=2, + ) + place_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + remove_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=4, + message=timestamp_pb2.Timestamp, + ) + allow_missing: bool = proto.Field( + proto.BOOL, + number=5, + ) + + +class RemoveFulfillmentPlacesMetadata(proto.Message): + r"""Metadata related to the progress of the RemoveFulfillmentPlaces + operation. Currently empty because there is no meaningful metadata + populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + method. + + """ + + +class RemoveFulfillmentPlacesResponse(proto.Message): + r"""Response of the RemoveFulfillmentPlacesRequest. Currently empty + because there is no meaningful response populated from the + [ProductService.RemoveFulfillmentPlaces][google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces] + method. + + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/promotion.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/promotion.py new file mode 100644 index 00000000..5b4c2136 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/promotion.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail.v2beta', + manifest={ + 'Promotion', + }, +) + + +class Promotion(proto.Message): + r"""Promotion information. + + Attributes: + promotion_id (str): + ID of the promotion. For example, "free gift". + + The value must be a UTF-8 encoded string with a length limit + of 128 characters, and match the pattern: + ``[a-zA-Z][a-zA-Z0-9_]*``. For example, id0LikeThis or + ID_1_LIKE_THIS. Otherwise, an INVALID_ARGUMENT error is + returned. + + Google Merchant Center property + `promotion `__. + """ + + promotion_id: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/purge_config.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/purge_config.py new file mode 100644 index 00000000..5a6cfb92 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/purge_config.py @@ -0,0 +1,111 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail.v2beta', + manifest={ + 'PurgeMetadata', + 'PurgeUserEventsRequest', + 'PurgeUserEventsResponse', + }, +) + + +class PurgeMetadata(proto.Message): + r"""Metadata related to the progress of the Purge operation. + This will be returned by the + google.longrunning.Operation.metadata field. + + """ + + +class PurgeUserEventsRequest(proto.Message): + r"""Request message for PurgeUserEvents method. + + Attributes: + parent (str): + Required. The resource name of the catalog under which the + events are created. The format is + ``projects/${projectId}/locations/global/catalogs/${catalogId}`` + filter (str): + Required. The filter string to specify the events to be + deleted with a length limit of 5,000 characters. Empty + string filter is not allowed. The eligible fields for + filtering are: + + - ``eventType``: Double quoted + [UserEvent.event_type][google.cloud.retail.v2beta.UserEvent.event_type] + string. + - ``eventTime``: in ISO 8601 "zulu" format. + - ``visitorId``: Double quoted string. Specifying this will + delete all events associated with a visitor. + - ``userId``: Double quoted string. Specifying this will + delete all events associated with a user. + + Examples: + + - Deleting all events in a time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventTime < "2012-04-23T18:30:43.511Z"`` + - Deleting specific eventType in time range: + ``eventTime > "2012-04-23T18:25:43.511Z" eventType = "detail-page-view"`` + - Deleting all events for a specific visitor: + ``visitorId = "visitor1024"`` + + The filtering fields are assumed to have an implicit AND. + force (bool): + Actually perform the purge. If ``force`` is set to false, + the method will return the expected purge count without + deleting any user events. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + filter: str = proto.Field( + proto.STRING, + number=2, + ) + force: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class PurgeUserEventsResponse(proto.Message): + r"""Response of the PurgeUserEventsRequest. If the long running + operation is successfully done, then this message is returned by + the google.longrunning.Operations.response field. + + Attributes: + purged_events_count (int): + The total count of events purged as a result + of the operation. + """ + + purged_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/search_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/search_service.py new file mode 100644 index 00000000..be9492ed --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/search_service.py @@ -0,0 +1,1417 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import product as gcr_product +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'SearchRequest', + 'SearchResponse', + 'ExperimentInfo', + }, +) + + +class SearchRequest(proto.Message): + r"""Request message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + method. + + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + placement (str): + Required. The resource name of the Retail Search serving + config, such as + ``projects/*/locations/global/catalogs/default_catalog/servingConfigs/default_serving_config`` + or the name of the legacy placement resource, such as + ``projects/*/locations/global/catalogs/default_catalog/placements/default_search``. + This field is used to identify the serving config name and + the set of models that will be used to make the search. + branch (str): + The branch resource name, such as + ``projects/*/locations/global/catalogs/default_catalog/branches/0``. + + Use "default_branch" as the branch ID or leave this field + empty, to search products under the default branch. + query (str): + Raw search query. + + If this field is empty, the request is considered a category + browsing request and returned results are based on + [filter][google.cloud.retail.v2beta.SearchRequest.filter] + and + [page_categories][google.cloud.retail.v2beta.SearchRequest.page_categories]. + visitor_id (str): + Required. A unique identifier for tracking visitors. For + example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor logs in or out of the website. + + This should be the same identifier as + [UserEvent.visitor_id][google.cloud.retail.v2beta.UserEvent.visitor_id]. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + user_info (google.cloud.retail_v2beta.types.UserInfo): + User information. + page_size (int): + Maximum number of + [Product][google.cloud.retail.v2beta.Product]s to return. If + unspecified, defaults to a reasonable value. The maximum + allowed value is 120. Values above 120 will be coerced to + 120. + + If this field is negative, an INVALID_ARGUMENT is returned. + page_token (str): + A page token + [SearchResponse.next_page_token][google.cloud.retail.v2beta.SearchResponse.next_page_token], + received from a previous + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + call. Provide this to retrieve the subsequent page. + + When paginating, all other parameters provided to + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + must match the call that provided the page token. Otherwise, + an INVALID_ARGUMENT error is returned. + offset (int): + A 0-indexed integer that specifies the current offset (that + is, starting result location, amongst the + [Product][google.cloud.retail.v2beta.Product]s deemed by the + API as relevant) in search results. This field is only + considered if + [page_token][google.cloud.retail.v2beta.SearchRequest.page_token] + is unset. + + If this field is negative, an INVALID_ARGUMENT is returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. Filter expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + canonical_filter (str): + The default filter that is applied when a user performs a + search without checking any filters on the search page. + + The filter applied to every search request when quality + improvement such as query expansion is needed. For example, + if a query does not have enough results, an expanded query + with + [SearchRequest.canonical_filter][google.cloud.retail.v2beta.SearchRequest.canonical_filter] + will be returned as a supplement of the original query. This + field is strongly recommended to achieve high search + quality. + + See + [SearchRequest.filter][google.cloud.retail.v2beta.SearchRequest.filter] + for more details about filter syntax. + order_by (str): + The order in which products are returned. Products can be + ordered by a field in an + [Product][google.cloud.retail.v2beta.Product] object. Leave + it unset if ordered by relevance. OrderBy expression is + case-sensitive. See more details at this `user + guide `__. + + If this field is unrecognizable, an INVALID_ARGUMENT is + returned. + facet_specs (MutableSequence[google.cloud.retail_v2beta.types.SearchRequest.FacetSpec]): + Facet specifications for faceted search. If empty, no facets + are returned. + + A maximum of 200 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + dynamic_facet_spec (google.cloud.retail_v2beta.types.SearchRequest.DynamicFacetSpec): + Deprecated. Refer to + https://cloud.google.com/retail/docs/configs#dynamic + to enable dynamic facets. Do not set this field. + + The specification for dynamically generated + facets. Notice that only textual facets can be + dynamically generated. + boost_spec (google.cloud.retail_v2beta.types.SearchRequest.BoostSpec): + Boost specification to boost certain products. See more + details at this `user + guide `__. + + Notice that if both + [ServingConfig.boost_control_ids][google.cloud.retail.v2beta.ServingConfig.boost_control_ids] + and + [SearchRequest.boost_spec][google.cloud.retail.v2beta.SearchRequest.boost_spec] + are set, the boost conditions from both places are + evaluated. If a search request matches multiple boost + conditions, the final boost score is equal to the sum of the + boost scores from all matched boost conditions. + query_expansion_spec (google.cloud.retail_v2beta.types.SearchRequest.QueryExpansionSpec): + The query expansion specification that specifies the + conditions under which query expansion will occur. See more + details at this `user + guide `__. + variant_rollup_keys (MutableSequence[str]): + The keys to fetch and rollup the matching + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s attributes, + [FulfillmentInfo][google.cloud.retail.v2beta.FulfillmentInfo] + or + [LocalInventory][google.cloud.retail.v2beta.LocalInventory]s + attributes. The attributes from all the matching + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s or + [LocalInventory][google.cloud.retail.v2beta.LocalInventory]s + are merged and de-duplicated. Notice that rollup attributes + will lead to extra query latency. Maximum number of keys is + 30. + + For + [FulfillmentInfo][google.cloud.retail.v2beta.FulfillmentInfo], + a fulfillment type and a fulfillment ID must be provided in + the format of "fulfillmentType.fulfillmentId". E.g., in + "pickupInStore.store123", "pickupInStore" is fulfillment + type and "store123" is the store ID. + + Supported keys are: + + - colorFamilies + - price + - originalPrice + - discount + - variantId + - inventory(place_id,price) + - inventory(place_id,original_price) + - inventory(place_id,attributes.key), where key is any key + in the + [Product.local_inventories.attributes][google.cloud.retail.v2beta.LocalInventory.attributes] + map. + - attributes.key, where key is any key in the + [Product.attributes][google.cloud.retail.v2beta.Product.attributes] + map. + - pickupInStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "pickup-in-store". + - shipToStore.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "ship-to-store". + - sameDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "same-day-delivery". + - nextDayDelivery.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "next-day-delivery". + - customFulfillment1.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "custom-type-1". + - customFulfillment2.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "custom-type-2". + - customFulfillment3.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "custom-type-3". + - customFulfillment4.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "custom-type-4". + - customFulfillment5.id, where id is any + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + for + [FulfillmentInfo.type][google.cloud.retail.v2beta.FulfillmentInfo.type] + "custom-type-5". + + If this field is set to an invalid value other than these, + an INVALID_ARGUMENT error is returned. + page_categories (MutableSequence[str]): + The categories associated with a category page. Must be set + for category navigation queries to achieve good search + quality. The format should be the same as + [UserEvent.page_categories][google.cloud.retail.v2beta.UserEvent.page_categories]; + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + search_mode (google.cloud.retail_v2beta.types.SearchRequest.SearchMode): + The search mode of the search request. If not + specified, a single search request triggers both + product search and faceted search. + personalization_spec (google.cloud.retail_v2beta.types.SearchRequest.PersonalizationSpec): + The specification for personalization. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec]. + labels (MutableMapping[str, str]): + The labels applied to a resource must meet the following + requirements: + + - Each resource can have multiple labels, up to a maximum + of 64. + - Each label must be a key-value pair. + - Keys have a minimum length of 1 character and a maximum + length of 63 characters and cannot be empty. Values can + be empty and have a maximum length of 63 characters. + - Keys and values can contain only lowercase letters, + numeric characters, underscores, and dashes. All + characters must use UTF-8 encoding, and international + characters are allowed. + - The key portion of a label must be unique. However, you + can use the same key with multiple resources. + - Keys must start with a lowercase letter or international + character. + + See `Google Cloud + Document `__ + for more details. + spell_correction_spec (google.cloud.retail_v2beta.types.SearchRequest.SpellCorrectionSpec): + The spell correction specification that + specifies the mode under which spell correction + will take effect. + + This field is a member of `oneof`_ ``_spell_correction_spec``. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. If this is set, it should be exactly + matched with + [UserEvent.entity][google.cloud.retail.v2beta.UserEvent.entity] + to get search results boosted by entity. + """ + class SearchMode(proto.Enum): + r"""The search mode of each search request. + + Values: + SEARCH_MODE_UNSPECIFIED (0): + Default value. In this case both product search and faceted + search will be performed. Both + [SearchResponse.SearchResult][google.cloud.retail.v2beta.SearchResponse.SearchResult] + and + [SearchResponse.Facet][google.cloud.retail.v2beta.SearchResponse.Facet] + will be returned. + PRODUCT_SEARCH_ONLY (1): + Only product search will be performed. The faceted search + will be disabled. + + Only + [SearchResponse.SearchResult][google.cloud.retail.v2beta.SearchResponse.SearchResult] + will be returned. + [SearchResponse.Facet][google.cloud.retail.v2beta.SearchResponse.Facet] + will not be returned, even if + [SearchRequest.facet_specs][google.cloud.retail.v2beta.SearchRequest.facet_specs] + or + [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2beta.SearchRequest.dynamic_facet_spec] + is set. + FACETED_SEARCH_ONLY (2): + Only faceted search will be performed. The product search + will be disabled. + + When in this mode, one or both of + [SearchRequest.facet_specs][google.cloud.retail.v2beta.SearchRequest.facet_specs] + and + [SearchRequest.dynamic_facet_spec][google.cloud.retail.v2beta.SearchRequest.dynamic_facet_spec] + should be set. Otherwise, an INVALID_ARGUMENT error is + returned. Only + [SearchResponse.Facet][google.cloud.retail.v2beta.SearchResponse.Facet] + will be returned. + [SearchResponse.SearchResult][google.cloud.retail.v2beta.SearchResponse.SearchResult] + will not be returned. + """ + SEARCH_MODE_UNSPECIFIED = 0 + PRODUCT_SEARCH_ONLY = 1 + FACETED_SEARCH_ONLY = 2 + + class FacetSpec(proto.Message): + r"""A facet specification to perform faceted search. + + Attributes: + facet_key (google.cloud.retail_v2beta.types.SearchRequest.FacetSpec.FacetKey): + Required. The facet key specification. + limit (int): + Maximum of facet values that should be returned for this + facet. If unspecified, defaults to 50. The maximum allowed + value is 300. Values above 300 will be coerced to 300. + + If this field is negative, an INVALID_ARGUMENT is returned. + excluded_filter_keys (MutableSequence[str]): + List of keys to exclude when faceting. + + By default, + [FacetKey.key][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.key] + is not excluded from the filter unless it is listed in this + field. + + Listing a facet key in this field allows its values to + appear as facet results, even when they are filtered out of + search results. Using this field does not affect what search + results are returned. + + For example, suppose there are 100 products with the color + facet "Red" and 200 products with the color facet "Blue". A + query containing the filter "colorFamilies:ANY("Red")" and + having "colorFamilies" as + [FacetKey.key][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.key] + would by default return only "Red" products in the search + results, and also return "Red" with count 100 as the only + color facet. Although there are also blue products + available, "Blue" would not be shown as an available facet + value. + + If "colorFamilies" is listed in "excludedFilterKeys", then + the query returns the facet values "Red" with count 100 and + "Blue" with count 200, because the "colorFamilies" key is + now excluded from the filter. Because this field doesn't + affect search results, the search results are still + correctly filtered to return only "Red" products. + + A maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + enable_dynamic_position (bool): + Enables dynamic position for this facet. If set to true, the + position of this facet among all facets in the response is + determined by Google Retail Search. It will be ordered + together with dynamic facets if dynamic facets is enabled. + If set to false, the position of this facet in the response + will be the same as in the request, and it will be ranked + before the facets with dynamic position enable and all + dynamic facets. + + For example, you may always want to have rating facet + returned in the response, but it's not necessarily to always + display the rating facet at the top. In that case, you can + set enable_dynamic_position to true so that the position of + rating facet in response will be determined by Google Retail + Search. + + Another example, assuming you have the following facets in + the request: + + - "rating", enable_dynamic_position = true + + - "price", enable_dynamic_position = false + + - "brands", enable_dynamic_position = false + + And also you have a dynamic facets enable, which will + generate a facet 'gender'. Then the final order of the + facets in the response can be ("price", "brands", "rating", + "gender") or ("price", "brands", "gender", "rating") depends + on how Google Retail Search orders "gender" and "rating" + facets. However, notice that "price" and "brands" will + always be ranked at 1st and 2nd position since their + enable_dynamic_position are false. + """ + + class FacetKey(proto.Message): + r"""Specifies how a facet is computed. + + Attributes: + key (str): + Required. Supported textual and numerical facet keys in + [Product][google.cloud.retail.v2beta.Product] object, over + which the facet values are computed. Facet key is + case-sensitive. + + Allowed facet keys when + [FacetKey.query][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.query] + is not specified: + + - textual_field = + + - "brands" + - "categories" + - "genders" + - "ageGroups" + - "availability" + - "colorFamilies" + - "colors" + - "sizes" + - "materials" + - "patterns" + - "conditions" + - "attributes.key" + - "pickupInStore" + - "shipToStore" + - "sameDayDelivery" + - "nextDayDelivery" + - "customFulfillment1" + - "customFulfillment2" + - "customFulfillment3" + - "customFulfillment4" + - "customFulfillment5" + - "inventory(place_id,attributes.key)" + + - numerical_field = + + - "price" + - "discount" + - "rating" + - "ratingCount" + - "attributes.key" + - "inventory(place_id,price)" + - "inventory(place_id,original_price)" + - "inventory(place_id,attributes.key)". + intervals (MutableSequence[google.cloud.retail_v2beta.types.Interval]): + Set only if values should be bucketized into + intervals. Must be set for facets with numerical + values. Must not be set for facet with text + values. Maximum number of intervals is 40. + + For all numerical facet keys that appear in the + list of products from the catalog, the + percentiles 0, 10, 30, 50, 70, 90 and 100 are + computed from their distribution weekly. If the + model assigns a high score to a numerical facet + key and its intervals are not specified in the + search request, these percentiles will become + the bounds for its intervals and will be + returned in the response. If the facet key + intervals are specified in the request, then the + specified intervals will be returned instead. + restricted_values (MutableSequence[str]): + Only get facet for the given restricted values. For example, + when using "pickupInStore" as key and set restricted values + to ["store123", "store456"], only facets for "store123" and + "store456" are returned. Only supported on predefined + textual fields, custom textual attributes and fulfillments. + Maximum is 20. + + Must be set for the fulfillment facet keys: + + - pickupInStore + + - shipToStore + + - sameDayDelivery + + - nextDayDelivery + + - customFulfillment1 + + - customFulfillment2 + + - customFulfillment3 + + - customFulfillment4 + + - customFulfillment5 + prefixes (MutableSequence[str]): + Only get facet values that start with the + given string prefix. For example, suppose + "categories" has three values "Women > Shoe", + "Women > Dress" and "Men > Shoe". If set + "prefixes" to "Women", the "categories" facet + will give only "Women > Shoe" and "Women > + Dress". Only supported on textual fields. + Maximum is 10. + contains (MutableSequence[str]): + Only get facet values that contains the given + strings. For example, suppose "categories" has + three values "Women > Shoe", "Women > Dress" and + "Men > Shoe". If set "contains" to "Shoe", the + "categories" facet will give only "Women > Shoe" + and "Men > Shoe". Only supported on textual + fields. Maximum is 10. + case_insensitive (bool): + True to make facet keys case insensitive when + getting faceting values with prefixes or + contains; false otherwise. + order_by (str): + The order in which + [SearchResponse.Facet.values][google.cloud.retail.v2beta.SearchResponse.Facet.values] + are returned. + + Allowed values are: + + - "count desc", which means order by + [SearchResponse.Facet.values.count][google.cloud.retail.v2beta.SearchResponse.Facet.FacetValue.count] + descending. + + - "value desc", which means order by + [SearchResponse.Facet.values.value][google.cloud.retail.v2beta.SearchResponse.Facet.FacetValue.value] + descending. Only applies to textual facets. + + If not set, textual values are sorted in `natural + order `__; + numerical intervals are sorted in the order given by + [FacetSpec.FacetKey.intervals][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.intervals]; + [FulfillmentInfo.place_ids][google.cloud.retail.v2beta.FulfillmentInfo.place_ids] + are sorted in the order given by + [FacetSpec.FacetKey.restricted_values][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.restricted_values]. + query (str): + The query that is used to compute facet for the given facet + key. When provided, it will override the default behavior of + facet computation. The query syntax is the same as a filter + expression. See + [SearchRequest.filter][google.cloud.retail.v2beta.SearchRequest.filter] + for detail syntax and limitations. Notice that there is no + limitation on + [FacetKey.key][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.key] + when query is specified. + + In the response, + [SearchResponse.Facet.values.value][google.cloud.retail.v2beta.SearchResponse.Facet.FacetValue.value] + will be always "1" and + [SearchResponse.Facet.values.count][google.cloud.retail.v2beta.SearchResponse.Facet.FacetValue.count] + will be the number of results that match the query. + + For example, you can set a customized facet for + "shipToStore", where + [FacetKey.key][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.key] + is "customizedShipToStore", and + [FacetKey.query][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.query] + is "availability: ANY("IN_STOCK") AND shipToStore: + ANY("123")". Then the facet will count the products that are + both in stock and ship to store "123". + return_min_max (bool): + Returns the min and max value for each + numerical facet intervals. Ignored for textual + facets. + """ + + key: str = proto.Field( + proto.STRING, + number=1, + ) + intervals: MutableSequence[common.Interval] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=common.Interval, + ) + restricted_values: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + prefixes: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=8, + ) + contains: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + case_insensitive: bool = proto.Field( + proto.BOOL, + number=10, + ) + order_by: str = proto.Field( + proto.STRING, + number=4, + ) + query: str = proto.Field( + proto.STRING, + number=5, + ) + return_min_max: bool = proto.Field( + proto.BOOL, + number=11, + ) + + facet_key: 'SearchRequest.FacetSpec.FacetKey' = proto.Field( + proto.MESSAGE, + number=1, + message='SearchRequest.FacetSpec.FacetKey', + ) + limit: int = proto.Field( + proto.INT32, + number=2, + ) + excluded_filter_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=3, + ) + enable_dynamic_position: bool = proto.Field( + proto.BOOL, + number=4, + ) + + class DynamicFacetSpec(proto.Message): + r"""The specifications of dynamically generated facets. + + Attributes: + mode (google.cloud.retail_v2beta.types.SearchRequest.DynamicFacetSpec.Mode): + Mode of the DynamicFacet feature. Defaults to + [Mode.DISABLED][google.cloud.retail.v2beta.SearchRequest.DynamicFacetSpec.Mode.DISABLED] + if it's unset. + """ + class Mode(proto.Enum): + r"""Enum to control DynamicFacet mode + + Values: + MODE_UNSPECIFIED (0): + Default value. + DISABLED (1): + Disable Dynamic Facet. + ENABLED (2): + Automatic mode built by Google Retail Search. + """ + MODE_UNSPECIFIED = 0 + DISABLED = 1 + ENABLED = 2 + + mode: 'SearchRequest.DynamicFacetSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.DynamicFacetSpec.Mode', + ) + + class BoostSpec(proto.Message): + r"""Boost specification to boost certain items. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + condition_boost_specs (MutableSequence[google.cloud.retail_v2beta.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + Condition boost specifications. If a product + matches multiple conditions in the + specifictions, boost scores from these + specifications are all applied and combined in a + non-linear way. Maximum number of specifications + is 20. + skip_boost_spec_validation (bool): + Whether to skip boostspec validation. If this field is set + to true, invalid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2beta.SearchRequest.BoostSpec.condition_boost_specs] + will be ignored and valid + [BoostSpec.condition_boost_specs][google.cloud.retail.v2beta.SearchRequest.BoostSpec.condition_boost_specs] + will still be applied. + + This field is a member of `oneof`_ ``_skip_boost_spec_validation``. + """ + + class ConditionBoostSpec(proto.Message): + r"""Boost applies to products which match a condition. + + Attributes: + condition (str): + An expression which specifies a boost condition. The syntax + and supported fields are the same as a filter expression. + See + [SearchRequest.filter][google.cloud.retail.v2beta.SearchRequest.filter] + for detail syntax and limitations. + + Examples: + + - To boost products with product ID "product_1" or + "product_2", and color "Red" or "Blue": + + - (id: ANY("product_1", "product_2")) AND + (colorFamilies: ANY("Red","Blue")) + boost (float): + Strength of the condition boost, which should be in [-1, 1]. + Negative boost means demotion. Default is 0.0. + + Setting to 1.0 gives the item a big promotion. However, it + does not necessarily mean that the boosted item will be the + top result at all times, nor that other items will be + excluded. Results could still be shown even when none of + them matches the condition. And results that are + significantly more relevant to the search query can still + trump your heavily favored but irrelevant items. + + Setting to -1.0 gives the item a big demotion. However, + results that are deeply relevant might still be shown. The + item will have an upstream battle to get a fairly high + ranking, but it is not blocked out completely. + + Setting to 0.0 means no boost applied. The boosting + condition is ignored. + """ + + condition: str = proto.Field( + proto.STRING, + number=1, + ) + boost: float = proto.Field( + proto.FLOAT, + number=2, + ) + + condition_boost_specs: MutableSequence['SearchRequest.BoostSpec.ConditionBoostSpec'] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message='SearchRequest.BoostSpec.ConditionBoostSpec', + ) + skip_boost_spec_validation: bool = proto.Field( + proto.BOOL, + number=2, + optional=True, + ) + + class QueryExpansionSpec(proto.Message): + r"""Specification to determine under which conditions query + expansion should occur. + + Attributes: + condition (google.cloud.retail_v2beta.types.SearchRequest.QueryExpansionSpec.Condition): + The condition under which query expansion should occur. + Default to + [Condition.DISABLED][google.cloud.retail.v2beta.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. + pin_unexpanded_results (bool): + Whether to pin unexpanded results. If this + field is set to true, unexpanded products are + always at the top of the search results, + followed by the expanded results. + """ + class Condition(proto.Enum): + r"""Enum describing under which condition query expansion should + occur. + + Values: + CONDITION_UNSPECIFIED (0): + Unspecified query expansion condition. In this case, server + behavior defaults to + [Condition.DISABLED][google.cloud.retail.v2beta.SearchRequest.QueryExpansionSpec.Condition.DISABLED]. + DISABLED (1): + Disabled query expansion. Only the exact search query is + used, even if + [SearchResponse.total_size][google.cloud.retail.v2beta.SearchResponse.total_size] + is zero. + AUTO (3): + Automatic query expansion built by Google + Retail Search. + """ + CONDITION_UNSPECIFIED = 0 + DISABLED = 1 + AUTO = 3 + + condition: 'SearchRequest.QueryExpansionSpec.Condition' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.QueryExpansionSpec.Condition', + ) + pin_unexpanded_results: bool = proto.Field( + proto.BOOL, + number=2, + ) + + class PersonalizationSpec(proto.Message): + r"""The specification for personalization. + + Attributes: + mode (google.cloud.retail_v2beta.types.SearchRequest.PersonalizationSpec.Mode): + Defaults to + [Mode.AUTO][google.cloud.retail.v2beta.SearchRequest.PersonalizationSpec.Mode.AUTO]. + """ + class Mode(proto.Enum): + r"""The personalization mode of each search request. + + Values: + MODE_UNSPECIFIED (0): + Default value. In this case, server behavior defaults to + [Mode.AUTO][google.cloud.retail.v2beta.SearchRequest.PersonalizationSpec.Mode.AUTO]. + AUTO (1): + Let CRS decide whether to use personalization + based on quality of user event data. + DISABLED (2): + Disable personalization. + """ + MODE_UNSPECIFIED = 0 + AUTO = 1 + DISABLED = 2 + + mode: 'SearchRequest.PersonalizationSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.PersonalizationSpec.Mode', + ) + + class SpellCorrectionSpec(proto.Message): + r"""The specification for query spell correction. + + Attributes: + mode (google.cloud.retail_v2beta.types.SearchRequest.SpellCorrectionSpec.Mode): + The mode under which spell correction should take effect to + replace the original search query. Default to + [Mode.AUTO][google.cloud.retail.v2beta.SearchRequest.SpellCorrectionSpec.Mode.AUTO]. + """ + class Mode(proto.Enum): + r"""Enum describing under which mode spell correction should + occur. + + Values: + MODE_UNSPECIFIED (0): + Unspecified spell correction mode. In this case, server + behavior defaults to + [Mode.AUTO][google.cloud.retail.v2beta.SearchRequest.SpellCorrectionSpec.Mode.AUTO]. + SUGGESTION_ONLY (1): + Google Retail Search will try to find a spell suggestion if + there is any and put in the + [SearchResponse.corrected_query][google.cloud.retail.v2beta.SearchResponse.corrected_query]. + The spell suggestion will not be used as the search query. + AUTO (2): + Automatic spell correction built by Google + Retail Search. Search will be based on the + corrected query if found. + """ + MODE_UNSPECIFIED = 0 + SUGGESTION_ONLY = 1 + AUTO = 2 + + mode: 'SearchRequest.SpellCorrectionSpec.Mode' = proto.Field( + proto.ENUM, + number=1, + enum='SearchRequest.SpellCorrectionSpec.Mode', + ) + + placement: str = proto.Field( + proto.STRING, + number=1, + ) + branch: str = proto.Field( + proto.STRING, + number=2, + ) + query: str = proto.Field( + proto.STRING, + number=3, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=4, + ) + user_info: common.UserInfo = proto.Field( + proto.MESSAGE, + number=5, + message=common.UserInfo, + ) + page_size: int = proto.Field( + proto.INT32, + number=7, + ) + page_token: str = proto.Field( + proto.STRING, + number=8, + ) + offset: int = proto.Field( + proto.INT32, + number=9, + ) + filter: str = proto.Field( + proto.STRING, + number=10, + ) + canonical_filter: str = proto.Field( + proto.STRING, + number=28, + ) + order_by: str = proto.Field( + proto.STRING, + number=11, + ) + facet_specs: MutableSequence[FacetSpec] = proto.RepeatedField( + proto.MESSAGE, + number=12, + message=FacetSpec, + ) + dynamic_facet_spec: DynamicFacetSpec = proto.Field( + proto.MESSAGE, + number=21, + message=DynamicFacetSpec, + ) + boost_spec: BoostSpec = proto.Field( + proto.MESSAGE, + number=13, + message=BoostSpec, + ) + query_expansion_spec: QueryExpansionSpec = proto.Field( + proto.MESSAGE, + number=14, + message=QueryExpansionSpec, + ) + variant_rollup_keys: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=17, + ) + page_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=23, + ) + search_mode: SearchMode = proto.Field( + proto.ENUM, + number=31, + enum=SearchMode, + ) + personalization_spec: PersonalizationSpec = proto.Field( + proto.MESSAGE, + number=32, + message=PersonalizationSpec, + ) + labels: MutableMapping[str, str] = proto.MapField( + proto.STRING, + proto.STRING, + number=34, + ) + spell_correction_spec: SpellCorrectionSpec = proto.Field( + proto.MESSAGE, + number=35, + optional=True, + message=SpellCorrectionSpec, + ) + entity: str = proto.Field( + proto.STRING, + number=38, + ) + + +class SearchResponse(proto.Message): + r"""Response message for + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search] + method. + + Attributes: + results (MutableSequence[google.cloud.retail_v2beta.types.SearchResponse.SearchResult]): + A list of matched items. The order represents + the ranking. + facets (MutableSequence[google.cloud.retail_v2beta.types.SearchResponse.Facet]): + Results of facets requested by user. + total_size (int): + The estimated total count of matched items irrespective of + pagination. The count of + [results][google.cloud.retail.v2beta.SearchResponse.results] + returned by pagination may be less than the + [total_size][google.cloud.retail.v2beta.SearchResponse.total_size] + that matches. + corrected_query (str): + Contains the spell corrected query, if found. If the spell + correction type is AUTOMATIC, then the search results are + based on corrected_query. Otherwise the original query is + used for search. + attribution_token (str): + A unique search token. This should be included in the + [UserEvent][google.cloud.retail.v2beta.UserEvent] logs + resulting from this search, which enables accurate + attribution of search model performance. + next_page_token (str): + A token that can be sent as + [SearchRequest.page_token][google.cloud.retail.v2beta.SearchRequest.page_token] + to retrieve the next page. If this field is omitted, there + are no subsequent pages. + query_expansion_info (google.cloud.retail_v2beta.types.SearchResponse.QueryExpansionInfo): + Query expansion information for the returned + results. + redirect_uri (str): + The URI of a customer-defined redirect page. If redirect + action is triggered, no search is performed, and only + [redirect_uri][google.cloud.retail.v2beta.SearchResponse.redirect_uri] + and + [attribution_token][google.cloud.retail.v2beta.SearchResponse.attribution_token] + are set in the response. + applied_controls (MutableSequence[str]): + The fully qualified resource name of applied + `controls `__. + invalid_condition_boost_specs (MutableSequence[google.cloud.retail_v2beta.types.SearchRequest.BoostSpec.ConditionBoostSpec]): + The invalid + [SearchRequest.BoostSpec.condition_boost_specs][google.cloud.retail.v2beta.SearchRequest.BoostSpec.condition_boost_specs] + that are not applied during serving. + experiment_info (MutableSequence[google.cloud.retail_v2beta.types.ExperimentInfo]): + Metadata related to A/B testing [Experiment][] associated + with this response. Only exists when an experiment is + triggered. + """ + + class SearchResult(proto.Message): + r"""Represents the search results. + + Attributes: + id (str): + [Product.id][google.cloud.retail.v2beta.Product.id] of the + searched [Product][google.cloud.retail.v2beta.Product]. + product (google.cloud.retail_v2beta.types.Product): + The product data snippet in the search response. Only + [Product.name][google.cloud.retail.v2beta.Product.name] is + guaranteed to be populated. + + [Product.variants][google.cloud.retail.v2beta.Product.variants] + contains the product variants that match the search query. + If there are multiple product variants matching the query, + top 5 most relevant product variants are returned and + ordered by relevancy. + + If relevancy can be deternmined, use + [matching_variant_fields][google.cloud.retail.v2beta.SearchResponse.SearchResult.matching_variant_fields] + to look up matched product variants fields. If relevancy + cannot be determined, e.g. when searching "shoe" all + products in a shoe product can be a match, 5 product + variants are returned but order is meaningless. + matching_variant_count (int): + The count of matched + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product]s. + matching_variant_fields (MutableMapping[str, google.protobuf.field_mask_pb2.FieldMask]): + If a + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product] matches the + search query, this map indicates which + [Product][google.cloud.retail.v2beta.Product] fields are + matched. The key is the + [Product.name][google.cloud.retail.v2beta.Product.name], the + value is a field mask of the matched + [Product][google.cloud.retail.v2beta.Product] fields. If + matched attributes cannot be determined, this map will be + empty. + + For example, a key "sku1" with field mask + "products.color_info" indicates there is a match between + "sku1" [ColorInfo][google.cloud.retail.v2beta.ColorInfo] and + the query. + variant_rollup_values (MutableMapping[str, google.protobuf.struct_pb2.Value]): + The rollup matching + [variant][google.cloud.retail.v2beta.Product.Type.VARIANT] + [Product][google.cloud.retail.v2beta.Product] attributes. + The key is one of the + [SearchRequest.variant_rollup_keys][google.cloud.retail.v2beta.SearchRequest.variant_rollup_keys]. + The values are the merged and de-duplicated + [Product][google.cloud.retail.v2beta.Product] attributes. + Notice that the rollup values are respect filter. For + example, when filtering by "colorFamilies:ANY("red")" and + rollup "colorFamilies", only "red" is returned. + + For textual and numerical attributes, the rollup values is a + list of string or double values with type + [google.protobuf.ListValue][google.protobuf.ListValue]. For + example, if there are two variants with colors "red" and + "blue", the rollup values are + + :: + + { key: "colorFamilies" + value { + list_value { + values { string_value: "red" } + values { string_value: "blue" } + } + } + } + + For + [FulfillmentInfo][google.cloud.retail.v2beta.FulfillmentInfo], + the rollup values is a double value with type + [google.protobuf.Value][google.protobuf.Value]. For example, + ``{key: "pickupInStore.store1" value { number_value: 10 }}`` + means a there are 10 variants in this product are available + in the store "store1". + personal_labels (MutableSequence[str]): + Specifies previous events related to this product for this + user based on + [UserEvent][google.cloud.retail.v2beta.UserEvent] with same + [SearchRequest.visitor_id][google.cloud.retail.v2beta.SearchRequest.visitor_id] + or + [UserInfo.user_id][google.cloud.retail.v2beta.UserInfo.user_id]. + + This is set only when + [SearchRequest.PersonalizationSpec.mode][google.cloud.retail.v2beta.SearchRequest.PersonalizationSpec.mode] + is + [SearchRequest.PersonalizationSpec.Mode.AUTO][google.cloud.retail.v2beta.SearchRequest.PersonalizationSpec.Mode.AUTO]. + + Possible values: + + - ``purchased``: Indicates that this product has been + purchased before. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_product.Product, + ) + matching_variant_count: int = proto.Field( + proto.INT32, + number=3, + ) + matching_variant_fields: MutableMapping[str, field_mask_pb2.FieldMask] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=4, + message=field_mask_pb2.FieldMask, + ) + variant_rollup_values: MutableMapping[str, struct_pb2.Value] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=5, + message=struct_pb2.Value, + ) + personal_labels: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + + class Facet(proto.Message): + r"""A facet result. + + Attributes: + key (str): + The key for this facet. E.g., "colorFamilies" + or "price" or "attributes.attr1". + values (MutableSequence[google.cloud.retail_v2beta.types.SearchResponse.Facet.FacetValue]): + The facet values for this field. + dynamic_facet (bool): + Whether the facet is dynamically generated. + """ + + class FacetValue(proto.Message): + r"""A facet value which contains value names and their count. + + 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: + value (str): + Text value of a facet, such as "Black" for + facet "colorFamilies". + + This field is a member of `oneof`_ ``facet_value``. + interval (google.cloud.retail_v2beta.types.Interval): + Interval value for a facet, such as [10, 20) for facet + "price". + + This field is a member of `oneof`_ ``facet_value``. + count (int): + Number of items that have this facet value. + min_value (float): + The minimum value in the + [FacetValue.interval][google.cloud.retail.v2beta.SearchResponse.Facet.FacetValue.interval]. + Only supported on numerical facets and returned if + [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.return_min_max] + is true. + max_value (float): + The maximum value in the + [FacetValue.interval][google.cloud.retail.v2beta.SearchResponse.Facet.FacetValue.interval]. + Only supported on numerical facets and returned if + [SearchRequest.FacetSpec.FacetKey.return_min_max][google.cloud.retail.v2beta.SearchRequest.FacetSpec.FacetKey.return_min_max] + is true. + """ + + value: str = proto.Field( + proto.STRING, + number=1, + oneof='facet_value', + ) + interval: common.Interval = proto.Field( + proto.MESSAGE, + number=2, + oneof='facet_value', + message=common.Interval, + ) + count: int = proto.Field( + proto.INT64, + number=3, + ) + min_value: float = proto.Field( + proto.DOUBLE, + number=5, + ) + max_value: float = proto.Field( + proto.DOUBLE, + number=6, + ) + + key: str = proto.Field( + proto.STRING, + number=1, + ) + values: MutableSequence['SearchResponse.Facet.FacetValue'] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message='SearchResponse.Facet.FacetValue', + ) + dynamic_facet: bool = proto.Field( + proto.BOOL, + number=3, + ) + + class QueryExpansionInfo(proto.Message): + r"""Information describing query expansion including whether + expansion has occurred. + + Attributes: + expanded_query (bool): + Bool describing whether query expansion has + occurred. + pinned_result_count (int): + Number of pinned results. This field will only be set when + expansion happens and + [SearchRequest.QueryExpansionSpec.pin_unexpanded_results][google.cloud.retail.v2beta.SearchRequest.QueryExpansionSpec.pin_unexpanded_results] + is set to true. + """ + + expanded_query: bool = proto.Field( + proto.BOOL, + number=1, + ) + pinned_result_count: int = proto.Field( + proto.INT64, + number=2, + ) + + @property + def raw_page(self): + return self + + results: MutableSequence[SearchResult] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=SearchResult, + ) + facets: MutableSequence[Facet] = proto.RepeatedField( + proto.MESSAGE, + number=2, + message=Facet, + ) + total_size: int = proto.Field( + proto.INT32, + number=3, + ) + corrected_query: str = proto.Field( + proto.STRING, + number=4, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=5, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=6, + ) + query_expansion_info: QueryExpansionInfo = proto.Field( + proto.MESSAGE, + number=7, + message=QueryExpansionInfo, + ) + redirect_uri: str = proto.Field( + proto.STRING, + number=10, + ) + applied_controls: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + invalid_condition_boost_specs: MutableSequence['SearchRequest.BoostSpec.ConditionBoostSpec'] = proto.RepeatedField( + proto.MESSAGE, + number=14, + message='SearchRequest.BoostSpec.ConditionBoostSpec', + ) + experiment_info: MutableSequence['ExperimentInfo'] = proto.RepeatedField( + proto.MESSAGE, + number=17, + message='ExperimentInfo', + ) + + +class ExperimentInfo(proto.Message): + r"""Metadata for active A/B testing [Experiments][]. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + serving_config_experiment (google.cloud.retail_v2beta.types.ExperimentInfo.ServingConfigExperiment): + A/B test between existing Cloud Retail Search + [ServingConfig][google.cloud.retail.v2beta.ServingConfig]s. + + This field is a member of `oneof`_ ``experiment_metadata``. + experiment (str): + The fully qualified resource name of the experiment that + provides the serving config under test, should an active + experiment exist. For example: + ``projects/*/locations/global/catalogs/default_catalog/experiments/experiment_id`` + """ + + class ServingConfigExperiment(proto.Message): + r"""Metadata for active serving config A/B tests. + + Attributes: + original_serving_config (str): + The fully qualified resource name of the original + [SearchRequest.placement][google.cloud.retail.v2beta.SearchRequest.placement] + in the search request prior to reassignment by experiment + API. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + experiment_serving_config (str): + The fully qualified resource name of the serving config + [VariantArm.serving_config_id][] responsible for generating + the search response. For example: + ``projects/*/locations/*/catalogs/*/servingConfigs/*``. + """ + + original_serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + experiment_serving_config: str = proto.Field( + proto.STRING, + number=2, + ) + + serving_config_experiment: ServingConfigExperiment = proto.Field( + proto.MESSAGE, + number=2, + oneof='experiment_metadata', + message=ServingConfigExperiment, + ) + experiment: str = proto.Field( + proto.STRING, + number=1, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config.py new file mode 100644 index 00000000..e108aa63 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config.py @@ -0,0 +1,359 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import search_service + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'ServingConfig', + }, +) + + +class ServingConfig(proto.Message): + r"""Configures metadata that is used to generate serving time + results (e.g. search results or recommendation predictions). + + Attributes: + name (str): + Immutable. Fully qualified name + ``projects/*/locations/global/catalogs/*/servingConfig/*`` + display_name (str): + Required. The human readable serving config display name. + Used in Retail UI. + + This field must be a UTF-8 encoded string with a length + limit of 128 characters. Otherwise, an INVALID_ARGUMENT + error is returned. + model_id (str): + The id of the model in the same + [Catalog][google.cloud.retail.v2beta.Catalog] to use at + serving time. Currently only RecommendationModels are + supported: + https://cloud.google.com/retail/recommendations-ai/docs/create-models + Can be changed but only to a compatible model (e.g. + others-you-may-like CTR to others-you-may-like CVR). + + Required when + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + price_reranking_level (str): + How much price ranking we want in serving results. Price + reranking causes product items with a similar recommendation + probability to be ordered by price, with the highest-priced + items first. This setting could result in a decrease in + click-through and conversion rates. Allowed values are: + + - ``no-price-reranking`` + - ``low-price-reranking`` + - ``medium-price-reranking`` + - ``high-price-reranking`` + + If not specified, we choose default based on model type. + Default value: ``no-price-reranking``. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + facet_control_ids (MutableSequence[str]): + Facet specifications for faceted search. If empty, no facets + are returned. The ids refer to the ids of + [Control][google.cloud.retail.v2beta.Control] resources with + only the Facet control set. These controls are assumed to be + in the same [Catalog][google.cloud.retail.v2beta.Catalog] as + the + [ServingConfig][google.cloud.retail.v2beta.ServingConfig]. A + maximum of 100 values are allowed. Otherwise, an + INVALID_ARGUMENT error is returned. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + dynamic_facet_spec (google.cloud.retail_v2beta.types.SearchRequest.DynamicFacetSpec): + The specification for dynamically generated facets. Notice + that only textual facets can be dynamically generated. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + boost_control_ids (MutableSequence[str]): + Condition boost specifications. If a product matches + multiple conditions in the specifications, boost scores from + these specifications are all applied and combined in a + non-linear way. Maximum number of specifications is 100. + + Notice that if both + [ServingConfig.boost_control_ids][google.cloud.retail.v2beta.ServingConfig.boost_control_ids] + and + [SearchRequest.boost_spec][google.cloud.retail.v2beta.SearchRequest.boost_spec] + are set, the boost conditions from both places are + evaluated. If a search request matches multiple boost + conditions, the final boost score is equal to the sum of the + boost scores from all matched boost conditions. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + filter_control_ids (MutableSequence[str]): + Condition filter specifications. If a product matches + multiple conditions in the specifications, filters from + these specifications are all applied and combined via the + AND operator. Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + redirect_control_ids (MutableSequence[str]): + Condition redirect specifications. Only the first triggered + redirect action is applied, even if multiple apply. Maximum + number of specifications is 1000. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + twoway_synonyms_control_ids (MutableSequence[str]): + Condition synonyms specifications. If multiple syonyms + conditions match, all matching synonyms control in the list + will execute. Order of controls in the list will not matter. + Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + oneway_synonyms_control_ids (MutableSequence[str]): + Condition oneway synonyms specifications. If multiple oneway + synonyms conditions match, all matching oneway synonyms + controls in the list will execute. Order of controls in the + list will not matter. Maximum number of specifications is + 100. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + do_not_associate_control_ids (MutableSequence[str]): + Condition do not associate specifications. If multiple do + not associate conditions match, all matching do not + associate controls in the list will execute. + + - Order does not matter. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + replacement_control_ids (MutableSequence[str]): + Condition replacement specifications. + + - Applied according to the order in the list. + - A previously replaced term can not be re-replaced. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + ignore_control_ids (MutableSequence[str]): + Condition ignore specifications. If multiple ignore + conditions match, all matching ignore controls in the list + will execute. + + - Order does not matter. + - Maximum number of specifications is 100. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + diversity_level (str): + How much diversity to use in recommendation model results + e.g. ``medium-diversity`` or ``high-diversity``. Currently + supported values: + + - ``no-diversity`` + - ``low-diversity`` + - ``medium-diversity`` + - ``high-diversity`` + - ``auto-diversity`` + + If not specified, we choose default based on recommendation + model type. Default value: ``no-diversity``. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + diversity_type (google.cloud.retail_v2beta.types.ServingConfig.DiversityType): + What kind of diversity to use - data driven or rule based. + If unset, the server behavior defaults to + [RULE_BASED_DIVERSITY][google.cloud.retail.v2beta.ServingConfig.DiversityType.RULE_BASED_DIVERSITY]. + enable_category_filter_level (str): + Whether to add additional category filters on the + ``similar-items`` model. If not specified, we enable it by + default. Allowed values are: + + - ``no-category-match``: No additional filtering of + original results from the model and the customer's + filters. + - ``relaxed-category-match``: Only keep results with + categories that match at least one item categories in the + PredictRequests's context item. + + - If customer also sends filters in the PredictRequest, + then the results will satisfy both conditions (user + given and category match). + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_RECOMMENDATION][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_RECOMMENDATION]. + personalization_spec (google.cloud.retail_v2beta.types.SearchRequest.PersonalizationSpec): + The specification for personalization spec. + + Can only be set if + [solution_types][google.cloud.retail.v2beta.ServingConfig.solution_types] + is + [SOLUTION_TYPE_SEARCH][google.cloud.retail.v2main.SolutionType.SOLUTION_TYPE_SEARCH]. + + Notice that if both + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec] + and + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + are set. + [SearchRequest.personalization_spec][google.cloud.retail.v2beta.SearchRequest.personalization_spec] + will override + [ServingConfig.personalization_spec][google.cloud.retail.v2beta.ServingConfig.personalization_spec]. + solution_types (MutableSequence[google.cloud.retail_v2beta.types.SolutionType]): + Required. Immutable. Specifies the solution + types that a serving config can be associated + with. Currently we support setting only one type + of solution. + """ + class DiversityType(proto.Enum): + r"""What type of diversity - data or rule based. + + Values: + DIVERSITY_TYPE_UNSPECIFIED (0): + Default value. + RULE_BASED_DIVERSITY (2): + Rule based diversity. + DATA_DRIVEN_DIVERSITY (3): + Data driven diversity. + """ + DIVERSITY_TYPE_UNSPECIFIED = 0 + RULE_BASED_DIVERSITY = 2 + DATA_DRIVEN_DIVERSITY = 3 + + name: str = proto.Field( + proto.STRING, + number=1, + ) + display_name: str = proto.Field( + proto.STRING, + number=2, + ) + model_id: str = proto.Field( + proto.STRING, + number=3, + ) + price_reranking_level: str = proto.Field( + proto.STRING, + number=4, + ) + facet_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=5, + ) + dynamic_facet_spec: search_service.SearchRequest.DynamicFacetSpec = proto.Field( + proto.MESSAGE, + number=6, + message=search_service.SearchRequest.DynamicFacetSpec, + ) + boost_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=7, + ) + filter_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=9, + ) + redirect_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=10, + ) + twoway_synonyms_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=18, + ) + oneway_synonyms_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=12, + ) + do_not_associate_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=13, + ) + replacement_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=14, + ) + ignore_control_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=15, + ) + diversity_level: str = proto.Field( + proto.STRING, + number=8, + ) + diversity_type: DiversityType = proto.Field( + proto.ENUM, + number=20, + enum=DiversityType, + ) + enable_category_filter_level: str = proto.Field( + proto.STRING, + number=16, + ) + personalization_spec: search_service.SearchRequest.PersonalizationSpec = proto.Field( + proto.MESSAGE, + number=21, + message=search_service.SearchRequest.PersonalizationSpec, + ) + solution_types: MutableSequence[common.SolutionType] = proto.RepeatedField( + proto.ENUM, + number=19, + enum=common.SolutionType, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config_service.py new file mode 100644 index 00000000..3ccae396 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/serving_config_service.py @@ -0,0 +1,238 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import serving_config as gcr_serving_config +from google.protobuf import field_mask_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'CreateServingConfigRequest', + 'UpdateServingConfigRequest', + 'DeleteServingConfigRequest', + 'GetServingConfigRequest', + 'ListServingConfigsRequest', + 'ListServingConfigsResponse', + 'AddControlRequest', + 'RemoveControlRequest', + }, +) + + +class CreateServingConfigRequest(proto.Message): + r"""Request for CreateServingConfig method. + + Attributes: + parent (str): + Required. Full resource name of parent. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + serving_config (google.cloud.retail_v2beta.types.ServingConfig): + Required. The ServingConfig to create. + serving_config_id (str): + Required. The ID to use for the ServingConfig, which will + become the final component of the ServingConfig's resource + name. + + This value should be 4-63 characters, and valid characters + are /[a-z][0-9]-_/. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + serving_config: gcr_serving_config.ServingConfig = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_serving_config.ServingConfig, + ) + serving_config_id: str = proto.Field( + proto.STRING, + number=3, + ) + + +class UpdateServingConfigRequest(proto.Message): + r"""Request for UpdateServingConfig method. + + Attributes: + serving_config (google.cloud.retail_v2beta.types.ServingConfig): + Required. The ServingConfig to update. + update_mask (google.protobuf.field_mask_pb2.FieldMask): + Indicates which fields in the provided + [ServingConfig][google.cloud.retail.v2beta.ServingConfig] to + update. The following are NOT supported: + + - [ServingConfig.name][google.cloud.retail.v2beta.ServingConfig.name] + + If not set, all supported fields are updated. + """ + + serving_config: gcr_serving_config.ServingConfig = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_serving_config.ServingConfig, + ) + update_mask: field_mask_pb2.FieldMask = proto.Field( + proto.MESSAGE, + number=2, + message=field_mask_pb2.FieldMask, + ) + + +class DeleteServingConfigRequest(proto.Message): + r"""Request for DeleteServingConfig method. + + Attributes: + name (str): + Required. The resource name of the ServingConfig to delete. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class GetServingConfigRequest(proto.Message): + r"""Request for GetServingConfig method. + + Attributes: + name (str): + Required. The resource name of the ServingConfig to get. + Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + """ + + name: str = proto.Field( + proto.STRING, + number=1, + ) + + +class ListServingConfigsRequest(proto.Message): + r"""Request for ListServingConfigs method. + + Attributes: + parent (str): + Required. The catalog resource name. Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}`` + page_size (int): + Optional. Maximum number of results to + return. If unspecified, defaults to 100. If a + value greater than 100 is provided, at most 100 + results are returned. + page_token (str): + Optional. A page token, received from a previous + ``ListServingConfigs`` call. Provide this to retrieve the + subsequent page. + """ + + 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 ListServingConfigsResponse(proto.Message): + r"""Response for ListServingConfigs method. + + Attributes: + serving_configs (MutableSequence[google.cloud.retail_v2beta.types.ServingConfig]): + All the ServingConfigs for a given catalog. + next_page_token (str): + Pagination token, if not returned indicates + the last page. + """ + + @property + def raw_page(self): + return self + + serving_configs: MutableSequence[gcr_serving_config.ServingConfig] = proto.RepeatedField( + proto.MESSAGE, + number=1, + message=gcr_serving_config.ServingConfig, + ) + next_page_token: str = proto.Field( + proto.STRING, + number=2, + ) + + +class AddControlRequest(proto.Message): + r"""Request for AddControl method. + + Attributes: + serving_config (str): + Required. The source ServingConfig resource name . Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + control_id (str): + Required. The id of the control to apply. Assumed to be in + the same catalog as the serving config - if id is not found + a NOT_FOUND error is returned. + """ + + serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + control_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +class RemoveControlRequest(proto.Message): + r"""Request for RemoveControl method. + + Attributes: + serving_config (str): + Required. The source ServingConfig resource name . Format: + ``projects/{project_number}/locations/{location_id}/catalogs/{catalog_id}/servingConfigs/{serving_config_id}`` + control_id (str): + Required. The id of the control to apply. + Assumed to be in the same catalog as the serving + config. + """ + + serving_config: str = proto.Field( + proto.STRING, + number=1, + ) + control_id: str = proto.Field( + proto.STRING, + number=2, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event.py new file mode 100644 index 00000000..9421c5d0 --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event.py @@ -0,0 +1,526 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import product as gcr_product +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'UserEvent', + 'ProductDetail', + 'CompletionDetail', + 'PurchaseTransaction', + }, +) + + +class UserEvent(proto.Message): + r"""UserEvent captures all metadata information Retail API needs + to know about how end users interact with customers' website. + + Attributes: + event_type (str): + Required. User event type. Allowed values are: + + - ``add-to-cart``: Products being added to cart. + - ``category-page-view``: Special pages such as sale or + promotion pages viewed. + - ``detail-page-view``: Products detail page viewed. + - ``home-page-view``: Homepage viewed. + - ``promotion-offered``: Promotion is offered to a user. + - ``promotion-not-offered``: Promotion is not offered to a + user. + - ``purchase-complete``: User finishing a purchase. + - ``search``: Product search. + - ``shopping-cart-page-view``: User viewing a shopping + cart. + visitor_id (str): + Required. A unique identifier for tracking visitors. + + For example, this could be implemented with an HTTP cookie, + which should be able to uniquely identify a visitor on a + single device. This unique identifier should not change if + the visitor log in/out of the website. + + Don't set the field to the same fixed ID for different + users. This mixes the event history of those users together, + which results in degraded model quality. + + The field must be a UTF-8 encoded string with a length limit + of 128 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + The field should not contain PII or user-data. We recommend + to use Google Analytics `Client + ID `__ + for this field. + session_id (str): + A unique identifier for tracking a visitor session with a + length limit of 128 bytes. A session is an aggregation of an + end user behavior in a time span. + + A general guideline to populate the sesion_id: + + 1. If user has no activity for 30 min, a new session_id + should be assigned. + 2. The session_id should be unique across users, suggest use + uuid or add visitor_id as prefix. + event_time (google.protobuf.timestamp_pb2.Timestamp): + Only required for + [UserEventService.ImportUserEvents][google.cloud.retail.v2beta.UserEventService.ImportUserEvents] + method. Timestamp of when the user event happened. + experiment_ids (MutableSequence[str]): + A list of identifiers for the independent + experiment groups this user event belongs to. + This is used to distinguish between user events + associated with different experiment setups + (e.g. using Retail API, using different + recommendation models). + attribution_token (str): + Highly recommended for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2beta.PredictionService.Predict]. + This field enables accurate attribution of recommendation + model performance. + + The value must be a valid + [PredictResponse.attribution_token][google.cloud.retail.v2beta.PredictResponse.attribution_token] + for user events that are the result of + [PredictionService.Predict][google.cloud.retail.v2beta.PredictionService.Predict]. + The value must be a valid + [SearchResponse.attribution_token][google.cloud.retail.v2beta.SearchResponse.attribution_token] + for user events that are the result of + [SearchService.Search][google.cloud.retail.v2beta.SearchService.Search]. + + This token enables us to accurately attribute page view or + purchase back to the event and the particular predict + response containing this clicked/purchased product. If user + clicks on product K in the recommendation results, pass + [PredictResponse.attribution_token][google.cloud.retail.v2beta.PredictResponse.attribution_token] + as a URL parameter to product K's page. When recording + events on product K's page, log the + [PredictResponse.attribution_token][google.cloud.retail.v2beta.PredictResponse.attribution_token] + to this field. + product_details (MutableSequence[google.cloud.retail_v2beta.types.ProductDetail]): + The main product details related to the event. + + This field is optional except for the following event types: + + - ``add-to-cart`` + - ``detail-page-view`` + - ``purchase-complete`` + + In a ``search`` event, this field represents the products + returned to the end user on the current page (the end user + may have not finished browsing the whole page yet). When a + new page is returned to the end user, after + pagination/filtering/ordering even for the same query, a new + ``search`` event with different + [product_details][google.cloud.retail.v2beta.UserEvent.product_details] + is desired. The end user may have not finished browsing the + whole page yet. + completion_detail (google.cloud.retail_v2beta.types.CompletionDetail): + The main auto-completion details related to the event. + + This field should be set for ``search`` event when + autocomplete function is enabled and the user clicks a + suggestion for search. + attributes (MutableMapping[str, google.cloud.retail_v2beta.types.CustomAttribute]): + Extra user event features to include in the recommendation + model. + + If you provide custom attributes for ingested user events, + also include them in the user events that you associate with + prediction requests. Custom attribute formatting must be + consistent between imported events and events provided with + prediction requests. This lets the Retail API use those + custom attributes when training models and serving + predictions, which helps improve recommendation quality. + + This field needs to pass all below criteria, otherwise an + INVALID_ARGUMENT error is returned: + + - The key must be a UTF-8 encoded string with a length + limit of 5,000 characters. + - For text attributes, at most 400 values are allowed. + Empty values are not allowed. Each value must be a UTF-8 + encoded string with a length limit of 256 characters. + - For number attributes, at most 400 values are allowed. + + For product recommendations, an example of extra user + information is traffic_channel, which is how a user arrives + at the site. Users can arrive at the site by coming to the + site directly, coming through Google search, or in other + ways. + cart_id (str): + The ID or name of the associated shopping cart. This ID is + used to associate multiple items added or present in the + cart before purchase. + + This can only be set for ``add-to-cart``, + ``purchase-complete``, or ``shopping-cart-page-view`` + events. + purchase_transaction (google.cloud.retail_v2beta.types.PurchaseTransaction): + A transaction represents the entire purchase transaction. + + Required for ``purchase-complete`` events. Other event types + should not set this field. Otherwise, an INVALID_ARGUMENT + error is returned. + search_query (str): + The user's search query. + + See + [SearchRequest.query][google.cloud.retail.v2beta.SearchRequest.query] + for definition. + + The value must be a UTF-8 encoded string with a length limit + of 5,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + At least one of + [search_query][google.cloud.retail.v2beta.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2beta.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + filter (str): + The filter syntax consists of an expression language for + constructing a predicate from one or more fields of the + products being filtered. + + See + [SearchRequest.filter][google.cloud.retail.v2beta.SearchRequest.filter] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + order_by (str): + The order in which products are returned. + + See + [SearchRequest.order_by][google.cloud.retail.v2beta.SearchRequest.order_by] + for definition and syntax. + + The value must be a UTF-8 encoded string with a length limit + of 1,000 characters. Otherwise, an INVALID_ARGUMENT error is + returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + offset (int): + An integer that specifies the current offset for pagination + (the 0-indexed starting location, amongst the products + deemed by the API as relevant). + + See + [SearchRequest.offset][google.cloud.retail.v2beta.SearchRequest.offset] + for definition. + + If this field is negative, an INVALID_ARGUMENT is returned. + + This can only be set for ``search`` events. Other event + types should not set this field. Otherwise, an + INVALID_ARGUMENT error is returned. + page_categories (MutableSequence[str]): + The categories associated with a category page. + + To represent full path of category, use '>' sign to separate + different hierarchies. If '>' is part of the category name, + replace it with other character(s). + + Category pages include special pages such as sales or + promotions. For instance, a special sale page may have the + category hierarchy: "pageCategories" : ["Sales > 2017 Black + Friday Deals"]. + + Required for ``category-page-view`` events. At least one of + [search_query][google.cloud.retail.v2beta.UserEvent.search_query] + or + [page_categories][google.cloud.retail.v2beta.UserEvent.page_categories] + is required for ``search`` events. Other event types should + not set this field. Otherwise, an INVALID_ARGUMENT error is + returned. + user_info (google.cloud.retail_v2beta.types.UserInfo): + User information. + uri (str): + Complete URL (window.location.href) of the + user's current page. + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. Maximum length + 5,000 characters. + referrer_uri (str): + The referrer URL of the current page. + + When using the client side event reporting with + JavaScript pixel and Google Tag Manager, this + value is filled in automatically. + page_view_id (str): + A unique ID of a web page view. + + This should be kept the same for all user events triggered + from the same pageview. For example, an item detail page + view could trigger multiple events as the user is browsing + the page. The ``pageViewId`` property should be kept the + same for all these events so that they can be grouped + together properly. + + When using the client side event reporting with JavaScript + pixel and Google Tag Manager, this value is filled in + automatically. + entity (str): + The entity for customers that may run multiple different + entities, domains, sites or regions, for example, + ``Google US``, ``Google Ads``, ``Waymo``, ``google.com``, + ``youtube.com``, etc. It is recommended to set this field to + get better per-entity search, completion and prediction + results. + """ + + event_type: str = proto.Field( + proto.STRING, + number=1, + ) + visitor_id: str = proto.Field( + proto.STRING, + number=2, + ) + session_id: str = proto.Field( + proto.STRING, + number=21, + ) + event_time: timestamp_pb2.Timestamp = proto.Field( + proto.MESSAGE, + number=3, + message=timestamp_pb2.Timestamp, + ) + experiment_ids: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=4, + ) + attribution_token: str = proto.Field( + proto.STRING, + number=5, + ) + product_details: MutableSequence['ProductDetail'] = proto.RepeatedField( + proto.MESSAGE, + number=6, + message='ProductDetail', + ) + completion_detail: 'CompletionDetail' = proto.Field( + proto.MESSAGE, + number=22, + message='CompletionDetail', + ) + attributes: MutableMapping[str, common.CustomAttribute] = proto.MapField( + proto.STRING, + proto.MESSAGE, + number=7, + message=common.CustomAttribute, + ) + cart_id: str = proto.Field( + proto.STRING, + number=8, + ) + purchase_transaction: 'PurchaseTransaction' = proto.Field( + proto.MESSAGE, + number=9, + message='PurchaseTransaction', + ) + search_query: str = proto.Field( + proto.STRING, + number=10, + ) + filter: str = proto.Field( + proto.STRING, + number=16, + ) + order_by: str = proto.Field( + proto.STRING, + number=17, + ) + offset: int = proto.Field( + proto.INT32, + number=18, + ) + page_categories: MutableSequence[str] = proto.RepeatedField( + proto.STRING, + number=11, + ) + user_info: common.UserInfo = proto.Field( + proto.MESSAGE, + number=12, + message=common.UserInfo, + ) + uri: str = proto.Field( + proto.STRING, + number=13, + ) + referrer_uri: str = proto.Field( + proto.STRING, + number=14, + ) + page_view_id: str = proto.Field( + proto.STRING, + number=15, + ) + entity: str = proto.Field( + proto.STRING, + number=23, + ) + + +class ProductDetail(proto.Message): + r"""Detailed product information associated with a user event. + + Attributes: + product (google.cloud.retail_v2beta.types.Product): + Required. [Product][google.cloud.retail.v2beta.Product] + information. + + Required field(s): + + - [Product.id][google.cloud.retail.v2beta.Product.id] + + Optional override field(s): + + - [Product.price_info][google.cloud.retail.v2beta.Product.price_info] + + If any supported optional fields are provided, we will treat + them as a full override when looking up product information + from the catalog. Thus, it is important to ensure that the + overriding fields are accurate and complete. + + All other product fields are ignored and instead populated + via catalog lookup after event ingestion. + quantity (google.protobuf.wrappers_pb2.Int32Value): + Quantity of the product associated with the user event. + + For example, this field will be 2 if two products are added + to the shopping cart for ``purchase-complete`` event. + Required for ``add-to-cart`` and ``purchase-complete`` event + types. + """ + + product: gcr_product.Product = proto.Field( + proto.MESSAGE, + number=1, + message=gcr_product.Product, + ) + quantity: wrappers_pb2.Int32Value = proto.Field( + proto.MESSAGE, + number=2, + message=wrappers_pb2.Int32Value, + ) + + +class CompletionDetail(proto.Message): + r"""Detailed completion information including completion + attribution token and clicked completion info. + + Attributes: + completion_attribution_token (str): + Completion attribution token in + [CompleteQueryResponse.attribution_token][google.cloud.retail.v2beta.CompleteQueryResponse.attribution_token]. + selected_suggestion (str): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2beta.CompleteQueryResponse.CompletionResult.suggestion]. + selected_position (int): + End user selected + [CompleteQueryResponse.CompletionResult.suggestion][google.cloud.retail.v2beta.CompleteQueryResponse.CompletionResult.suggestion] + position, starting from 0. + """ + + completion_attribution_token: str = proto.Field( + proto.STRING, + number=1, + ) + selected_suggestion: str = proto.Field( + proto.STRING, + number=2, + ) + selected_position: int = proto.Field( + proto.INT32, + number=3, + ) + + +class PurchaseTransaction(proto.Message): + r"""A transaction represents the entire purchase transaction. + + Attributes: + id (str): + The transaction ID with a length limit of 128 + characters. + revenue (float): + Required. Total non-zero revenue or grand + total associated with the transaction. This + value include shipping, tax, or other + adjustments to total revenue that you want to + include as part of your revenue calculations. + tax (float): + All the taxes associated with the + transaction. + cost (float): + All the costs associated with the products. These can be + manufacturing costs, shipping expenses not borne by the end + user, or any other costs, such that: + + - Profit = + [revenue][google.cloud.retail.v2beta.PurchaseTransaction.revenue] + - + [tax][google.cloud.retail.v2beta.PurchaseTransaction.tax] + - + [cost][google.cloud.retail.v2beta.PurchaseTransaction.cost] + currency_code (str): + Required. Currency code. Use three-character + ISO-4217 code. + """ + + id: str = proto.Field( + proto.STRING, + number=1, + ) + revenue: float = proto.Field( + proto.FLOAT, + number=2, + ) + tax: float = proto.Field( + proto.FLOAT, + number=3, + ) + cost: float = proto.Field( + proto.FLOAT, + number=4, + ) + currency_code: str = proto.Field( + proto.STRING, + number=5, + ) + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event_service.py b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event_service.py new file mode 100644 index 00000000..4b467b4f --- /dev/null +++ b/owl-bot-staging/v2beta/google/cloud/retail_v2beta/types/user_event_service.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 + +from google.cloud.retail_v2beta.types import user_event as gcr_user_event + + +__protobuf__ = proto.module( + package='google.cloud.retail.v2beta', + manifest={ + 'WriteUserEventRequest', + 'CollectUserEventRequest', + 'RejoinUserEventsRequest', + 'RejoinUserEventsResponse', + 'RejoinUserEventsMetadata', + }, +) + + +class WriteUserEventRequest(proto.Message): + r"""Request message for WriteUserEvent method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (google.cloud.retail_v2beta.types.UserEvent): + Required. User event to write. + write_async (bool): + If set to true, the user event will be + written asynchronously after validation, and the + API will respond without waiting for the write. + Therefore, silent failures can occur even if the + API returns success. In case of silent failures, + error messages can be found in Stackdriver logs. + """ + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: gcr_user_event.UserEvent = proto.Field( + proto.MESSAGE, + number=2, + message=gcr_user_event.UserEvent, + ) + write_async: bool = proto.Field( + proto.BOOL, + number=3, + ) + + +class CollectUserEventRequest(proto.Message): + r"""Request message for CollectUserEvent method. + + .. _oneof: https://proto-plus-python.readthedocs.io/en/stable/fields.html#oneofs-mutually-exclusive-fields + + Attributes: + prebuilt_rule (str): + The prebuilt rule name that can convert a specific type of + raw_json. For example: "ga4_bq" rule for the GA4 user event + schema. + + This field is a member of `oneof`_ ``conversion_rule``. + parent (str): + Required. The parent catalog name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event (str): + Required. URL encoded UserEvent proto with a + length limit of 2,000,000 characters. + uri (str): + The URL including cgi-parameters but + excluding the hash fragment with a length limit + of 5,000 characters. This is often more useful + than the referer URL, because many browsers only + send the domain for 3rd party requests. + ets (int): + The event timestamp in milliseconds. This + prevents browser caching of otherwise identical + get requests. The name is abbreviated to reduce + the payload bytes. + raw_json (str): + An arbitrary serialized JSON string that contains necessary + information that can comprise a user event. When this field + is specified, the user_event field will be ignored. Note: + line-delimited JSON is not supported, a single JSON only. + """ + + prebuilt_rule: str = proto.Field( + proto.STRING, + number=6, + oneof='conversion_rule', + ) + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event: str = proto.Field( + proto.STRING, + number=2, + ) + uri: str = proto.Field( + proto.STRING, + number=3, + ) + ets: int = proto.Field( + proto.INT64, + number=4, + ) + raw_json: str = proto.Field( + proto.STRING, + number=5, + ) + + +class RejoinUserEventsRequest(proto.Message): + r"""Request message for RejoinUserEvents method. + + Attributes: + parent (str): + Required. The parent catalog resource name, such as + ``projects/1234/locations/global/catalogs/default_catalog``. + user_event_rejoin_scope (google.cloud.retail_v2beta.types.RejoinUserEventsRequest.UserEventRejoinScope): + The type of the user event rejoin to define the scope and + range of the user events to be rejoined with the latest + product catalog. Defaults to + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED`` if this field is not + set, or set to an invalid integer value. + """ + class UserEventRejoinScope(proto.Enum): + r"""The scope of user events to be rejoined with the latest product + catalog. If the rejoining aims at reducing number of unjoined + events, set ``UserEventRejoinScope`` to ``UNJOINED_EVENTS``. If the + rejoining aims at correcting product catalog information in joined + events, set ``UserEventRejoinScope`` to ``JOINED_EVENTS``. If all + events needs to be rejoined, set ``UserEventRejoinScope`` to + ``USER_EVENT_REJOIN_SCOPE_UNSPECIFIED``. + + Values: + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED (0): + Rejoin all events with the latest product + catalog, including both joined events and + unjoined events. + JOINED_EVENTS (1): + Only rejoin joined events with the latest + product catalog. + UNJOINED_EVENTS (2): + Only rejoin unjoined events with the latest + product catalog. + """ + USER_EVENT_REJOIN_SCOPE_UNSPECIFIED = 0 + JOINED_EVENTS = 1 + UNJOINED_EVENTS = 2 + + parent: str = proto.Field( + proto.STRING, + number=1, + ) + user_event_rejoin_scope: UserEventRejoinScope = proto.Field( + proto.ENUM, + number=2, + enum=UserEventRejoinScope, + ) + + +class RejoinUserEventsResponse(proto.Message): + r"""Response message for ``RejoinUserEvents`` method. + + Attributes: + rejoined_user_events_count (int): + Number of user events that were joined with + latest product catalog. + """ + + rejoined_user_events_count: int = proto.Field( + proto.INT64, + number=1, + ) + + +class RejoinUserEventsMetadata(proto.Message): + r"""Metadata for ``RejoinUserEvents`` method. + """ + + +__all__ = tuple(sorted(__protobuf__.manifest)) diff --git a/owl-bot-staging/v2beta/mypy.ini b/owl-bot-staging/v2beta/mypy.ini new file mode 100644 index 00000000..574c5aed --- /dev/null +++ b/owl-bot-staging/v2beta/mypy.ini @@ -0,0 +1,3 @@ +[mypy] +python_version = 3.7 +namespace_packages = True diff --git a/owl-bot-staging/v2beta/noxfile.py b/owl-bot-staging/v2beta/noxfile.py new file mode 100644 index 00000000..d35af1aa --- /dev/null +++ b/owl-bot-staging/v2beta/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/retail_v2beta/', + '--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/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_async.py new file mode 100644 index 00000000..96849ad0 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_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 AddCatalogAttribute +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_AddCatalogAttribute_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 retail_v2beta + + +async def sample_add_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_AddCatalogAttribute_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_sync.py new file mode 100644 index 00000000..c35c7deb --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_add_catalog_attribute_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 AddCatalogAttribute +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_AddCatalogAttribute_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 retail_v2beta + + +def sample_add_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.AddCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.add_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_AddCatalogAttribute_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py new file mode 100644 index 00000000..3338c3a7 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_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 BatchRemoveCatalogAttributes +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_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 retail_v2beta + + +async def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = await client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py new file mode 100644 index 00000000..13b3c3f9 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_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 BatchRemoveCatalogAttributes +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_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 retail_v2beta + + +def sample_batch_remove_catalog_attributes(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.BatchRemoveCatalogAttributesRequest( + attributes_config="attributes_config_value", + attribute_keys=['attribute_keys_value1', 'attribute_keys_value2'], + ) + + # Make the request + response = client.batch_remove_catalog_attributes(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_async.py new file mode 100644 index 00000000..5593be93 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_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 GetAttributesConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_GetAttributesConfig_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 retail_v2beta + + +async def sample_get_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_GetAttributesConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_sync.py new file mode 100644 index 00000000..7113b9a7 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_attributes_config_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 GetAttributesConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_GetAttributesConfig_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 retail_v2beta + + +def sample_get_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetAttributesConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_GetAttributesConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_async.py new file mode 100644 index 00000000..ff880c6e --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_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 GetCompletionConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_GetCompletionConfig_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 retail_v2beta + + +async def sample_get_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_GetCompletionConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_sync.py new file mode 100644 index 00000000..824ed2ae --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_completion_config_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 GetCompletionConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_GetCompletionConfig_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 retail_v2beta + + +def sample_get_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetCompletionConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_GetCompletionConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_async.py new file mode 100644 index 00000000..aad2f652 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_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 GetDefaultBranch +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_GetDefaultBranch_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 retail_v2beta + + +async def sample_get_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetDefaultBranchRequest( + ) + + # Make the request + response = await client.get_default_branch(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_GetDefaultBranch_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_sync.py new file mode 100644 index 00000000..7440fd21 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_get_default_branch_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 GetDefaultBranch +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_GetDefaultBranch_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 retail_v2beta + + +def sample_get_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetDefaultBranchRequest( + ) + + # Make the request + response = client.get_default_branch(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_GetDefaultBranch_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_async.py new file mode 100644 index 00000000..c639caab --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_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 ListCatalogs +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_ListCatalogs_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 retail_v2beta + + +async def sample_list_catalogs(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2beta_generated_CatalogService_ListCatalogs_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_sync.py new file mode 100644 index 00000000..8ee8f27c --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_list_catalogs_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 ListCatalogs +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_ListCatalogs_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 retail_v2beta + + +def sample_list_catalogs(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListCatalogsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_catalogs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2beta_generated_CatalogService_ListCatalogs_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_async.py new file mode 100644 index 00000000..8cbd4f92 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_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 RemoveCatalogAttribute +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_RemoveCatalogAttribute_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 retail_v2beta + + +async def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = await client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_RemoveCatalogAttribute_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_sync.py new file mode 100644 index 00000000..a5c82a8a --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_remove_catalog_attribute_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 RemoveCatalogAttribute +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_RemoveCatalogAttribute_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 retail_v2beta + + +def sample_remove_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveCatalogAttributeRequest( + attributes_config="attributes_config_value", + key="key_value", + ) + + # Make the request + response = client.remove_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_RemoveCatalogAttribute_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_async.py new file mode 100644 index 00000000..47eb8e8d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_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 ReplaceCatalogAttribute +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_ReplaceCatalogAttribute_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 retail_v2beta + + +async def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = await client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_ReplaceCatalogAttribute_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_sync.py new file mode 100644 index 00000000..a8014c9b --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_replace_catalog_attribute_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 ReplaceCatalogAttribute +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_ReplaceCatalogAttribute_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 retail_v2beta + + +def sample_replace_catalog_attribute(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + catalog_attribute = retail_v2beta.CatalogAttribute() + catalog_attribute.key = "key_value" + + request = retail_v2beta.ReplaceCatalogAttributeRequest( + attributes_config="attributes_config_value", + catalog_attribute=catalog_attribute, + ) + + # Make the request + response = client.replace_catalog_attribute(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_ReplaceCatalogAttribute_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_async.py new file mode 100644 index 00000000..4e2ebe28 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_async.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetDefaultBranch +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_SetDefaultBranch_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 retail_v2beta + + +async def sample_set_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.SetDefaultBranchRequest( + ) + + # Make the request + await client.set_default_branch(request=request) + + +# [END retail_v2beta_generated_CatalogService_SetDefaultBranch_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_sync.py new file mode 100644 index 00000000..926ee306 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_set_default_branch_sync.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetDefaultBranch +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_SetDefaultBranch_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 retail_v2beta + + +def sample_set_default_branch(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.SetDefaultBranchRequest( + ) + + # Make the request + client.set_default_branch(request=request) + + +# [END retail_v2beta_generated_CatalogService_SetDefaultBranch_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_async.py new file mode 100644 index 00000000..99c6fa60 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_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 UpdateAttributesConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_UpdateAttributesConfig_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 retail_v2beta + + +async def sample_update_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + attributes_config = retail_v2beta.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2beta.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = await client.update_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_UpdateAttributesConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_sync.py new file mode 100644 index 00000000..2be343c7 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_attributes_config_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 UpdateAttributesConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_UpdateAttributesConfig_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 retail_v2beta + + +def sample_update_attributes_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + attributes_config = retail_v2beta.AttributesConfig() + attributes_config.name = "name_value" + + request = retail_v2beta.UpdateAttributesConfigRequest( + attributes_config=attributes_config, + ) + + # Make the request + response = client.update_attributes_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_UpdateAttributesConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_async.py new file mode 100644 index 00000000..4b0248c3 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_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 UpdateCatalog +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_UpdateCatalog_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 retail_v2beta + + +async def sample_update_catalog(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + catalog = retail_v2beta.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2beta.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = await client.update_catalog(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_UpdateCatalog_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_sync.py new file mode 100644 index 00000000..aa085779 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_catalog_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 UpdateCatalog +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_UpdateCatalog_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 retail_v2beta + + +def sample_update_catalog(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + catalog = retail_v2beta.Catalog() + catalog.name = "name_value" + catalog.display_name = "display_name_value" + + request = retail_v2beta.UpdateCatalogRequest( + catalog=catalog, + ) + + # Make the request + response = client.update_catalog(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_UpdateCatalog_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_async.py new file mode 100644 index 00000000..0c469792 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_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 UpdateCompletionConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_UpdateCompletionConfig_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 retail_v2beta + + +async def sample_update_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceAsyncClient() + + # Initialize request argument(s) + completion_config = retail_v2beta.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2beta.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = await client.update_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_UpdateCompletionConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_sync.py new file mode 100644 index 00000000..63d93bf5 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_catalog_service_update_completion_config_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 UpdateCompletionConfig +# 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-retail + + +# [START retail_v2beta_generated_CatalogService_UpdateCompletionConfig_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 retail_v2beta + + +def sample_update_completion_config(): + # Create a client + client = retail_v2beta.CatalogServiceClient() + + # Initialize request argument(s) + completion_config = retail_v2beta.CompletionConfig() + completion_config.name = "name_value" + + request = retail_v2beta.UpdateCompletionConfigRequest( + completion_config=completion_config, + ) + + # Make the request + response = client.update_completion_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CatalogService_UpdateCompletionConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_async.py new file mode 100644 index 00000000..119a1e95 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_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 CompleteQuery +# 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-retail + + +# [START retail_v2beta_generated_CompletionService_CompleteQuery_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 retail_v2beta + + +async def sample_complete_query(): + # Create a client + client = retail_v2beta.CompletionServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = await client.complete_query(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CompletionService_CompleteQuery_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_sync.py new file mode 100644 index 00000000..1ac32d5a --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_complete_query_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 CompleteQuery +# 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-retail + + +# [START retail_v2beta_generated_CompletionService_CompleteQuery_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 retail_v2beta + + +def sample_complete_query(): + # Create a client + client = retail_v2beta.CompletionServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.CompleteQueryRequest( + catalog="catalog_value", + query="query_value", + ) + + # Make the request + response = client.complete_query(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CompletionService_CompleteQuery_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_async.py new file mode 100644 index 00000000..bfc6821d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportCompletionData +# 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-retail + + +# [START retail_v2beta_generated_CompletionService_ImportCompletionData_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 retail_v2beta + + +async def sample_import_completion_data(): + # Create a client + client = retail_v2beta.CompletionServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2beta.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2beta.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CompletionService_ImportCompletionData_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_sync.py new file mode 100644 index 00000000..a1056ea7 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_completion_service_import_completion_data_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportCompletionData +# 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-retail + + +# [START retail_v2beta_generated_CompletionService_ImportCompletionData_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 retail_v2beta + + +def sample_import_completion_data(): + # Create a client + client = retail_v2beta.CompletionServiceClient() + + # Initialize request argument(s) + input_config = retail_v2beta.CompletionDataInputConfig() + input_config.big_query_source.dataset_id = "dataset_id_value" + input_config.big_query_source.table_id = "table_id_value" + + request = retail_v2beta.ImportCompletionDataRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_completion_data(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_CompletionService_ImportCompletionData_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_async.py new file mode 100644 index 00000000..2438b417 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_async.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_CreateControl_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 retail_v2beta + + +async def sample_create_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = await client.create_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ControlService_CreateControl_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_sync.py new file mode 100644 index 00000000..f0ace1be --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_create_control_sync.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_CreateControl_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 retail_v2beta + + +def sample_create_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateControlRequest( + parent="parent_value", + control=control, + control_id="control_id_value", + ) + + # Make the request + response = client.create_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ControlService_CreateControl_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_async.py new file mode 100644 index 00000000..20448a47 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_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 DeleteControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_DeleteControl_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 retail_v2beta + + +async def sample_delete_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteControlRequest( + name="name_value", + ) + + # Make the request + await client.delete_control(request=request) + + +# [END retail_v2beta_generated_ControlService_DeleteControl_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_sync.py new file mode 100644 index 00000000..68190a1e --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_delete_control_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 DeleteControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_DeleteControl_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 retail_v2beta + + +def sample_delete_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteControlRequest( + name="name_value", + ) + + # Make the request + client.delete_control(request=request) + + +# [END retail_v2beta_generated_ControlService_DeleteControl_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_async.py new file mode 100644 index 00000000..d41546d3 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_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 GetControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_GetControl_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 retail_v2beta + + +async def sample_get_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetControlRequest( + name="name_value", + ) + + # Make the request + response = await client.get_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ControlService_GetControl_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_sync.py new file mode 100644 index 00000000..251c3c8a --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_get_control_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 GetControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_GetControl_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 retail_v2beta + + +def sample_get_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetControlRequest( + name="name_value", + ) + + # Make the request + response = client.get_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ControlService_GetControl_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_async.py new file mode 100644 index 00000000..5c64c700 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_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 ListControls +# 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-retail + + +# [START retail_v2beta_generated_ControlService_ListControls_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 retail_v2beta + + +async def sample_list_controls(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2beta_generated_ControlService_ListControls_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_sync.py new file mode 100644 index 00000000..b47dc46d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_list_controls_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 ListControls +# 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-retail + + +# [START retail_v2beta_generated_ControlService_ListControls_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 retail_v2beta + + +def sample_list_controls(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListControlsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_controls(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2beta_generated_ControlService_ListControls_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_async.py new file mode 100644 index 00000000..65e40720 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_UpdateControl_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 retail_v2beta + + +async def sample_update_control(): + # Create a client + client = retail_v2beta.ControlServiceAsyncClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateControlRequest( + control=control, + ) + + # Make the request + response = await client.update_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ControlService_UpdateControl_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_sync.py new file mode 100644 index 00000000..a8f187ce --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_control_service_update_control_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateControl +# 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-retail + + +# [START retail_v2beta_generated_ControlService_UpdateControl_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 retail_v2beta + + +def sample_update_control(): + # Create a client + client = retail_v2beta.ControlServiceClient() + + # Initialize request argument(s) + control = retail_v2beta.Control() + control.facet_spec.facet_key.key = "key_value" + control.display_name = "display_name_value" + control.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateControlRequest( + control=control, + ) + + # Make the request + response = client.update_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ControlService_UpdateControl_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py new file mode 100644 index 00000000..1a9a419f --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_async.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_CreateModel_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 retail_v2beta + + +async def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_CreateModel_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py new file mode 100644 index 00000000..706acd44 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_create_model_sync.py @@ -0,0 +1,62 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_CreateModel_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 retail_v2beta + + +def sample_create_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.CreateModelRequest( + parent="parent_value", + model=model, + ) + + # Make the request + operation = client.create_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_CreateModel_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_async.py new file mode 100644 index 00000000..073277ea --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_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 DeleteModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_DeleteModel_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 retail_v2beta + + +async def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + await client.delete_model(request=request) + + +# [END retail_v2beta_generated_ModelService_DeleteModel_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_sync.py new file mode 100644 index 00000000..474ab84c --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_delete_model_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 DeleteModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_DeleteModel_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 retail_v2beta + + +def sample_delete_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteModelRequest( + name="name_value", + ) + + # Make the request + client.delete_model(request=request) + + +# [END retail_v2beta_generated_ModelService_DeleteModel_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_async.py new file mode 100644 index 00000000..861f2dcf --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_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 GetModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_GetModel_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 retail_v2beta + + +async def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = await client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_GetModel_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_sync.py new file mode 100644 index 00000000..5512c493 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_get_model_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 GetModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_GetModel_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 retail_v2beta + + +def sample_get_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetModelRequest( + name="name_value", + ) + + # Make the request + response = client.get_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_GetModel_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_async.py new file mode 100644 index 00000000..5cf30248 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_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 ListModels +# 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-retail + + +# [START retail_v2beta_generated_ModelService_ListModels_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 retail_v2beta + + +async def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2beta_generated_ModelService_ListModels_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_sync.py new file mode 100644 index 00000000..6a2334c8 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_list_models_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 ListModels +# 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-retail + + +# [START retail_v2beta_generated_ModelService_ListModels_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 retail_v2beta + + +def sample_list_models(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListModelsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_models(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2beta_generated_ModelService_ListModels_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_async.py new file mode 100644 index 00000000..cdacde42 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_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 PauseModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_PauseModel_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 retail_v2beta + + +async def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = await client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_PauseModel_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_sync.py new file mode 100644 index 00000000..ade34518 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_pause_model_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 PauseModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_PauseModel_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 retail_v2beta + + +def sample_pause_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.PauseModelRequest( + name="name_value", + ) + + # Make the request + response = client.pause_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_PauseModel_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_async.py new file mode 100644 index 00000000..14f9f378 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_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 ResumeModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_ResumeModel_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 retail_v2beta + + +async def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = await client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_ResumeModel_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_sync.py new file mode 100644 index 00000000..697b3a5c --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_resume_model_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 ResumeModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_ResumeModel_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 retail_v2beta + + +def sample_resume_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ResumeModelRequest( + name="name_value", + ) + + # Make the request + response = client.resume_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_ResumeModel_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_async.py new file mode 100644 index 00000000..a11b19ff --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_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 TuneModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_TuneModel_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 retail_v2beta + + +async def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_TuneModel_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_sync.py new file mode 100644 index 00000000..91d39965 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_tune_model_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 TuneModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_TuneModel_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 retail_v2beta + + +def sample_tune_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.TuneModelRequest( + name="name_value", + ) + + # Make the request + operation = client.tune_model(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_TuneModel_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_async.py new file mode 100644 index 00000000..d065538d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_UpdateModel_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 retail_v2beta + + +async def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceAsyncClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = await client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_UpdateModel_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_sync.py new file mode 100644 index 00000000..3cacfff1 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_model_service_update_model_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 UpdateModel +# 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-retail + + +# [START retail_v2beta_generated_ModelService_UpdateModel_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 retail_v2beta + + +def sample_update_model(): + # Create a client + client = retail_v2beta.ModelServiceClient() + + # Initialize request argument(s) + model = retail_v2beta.Model() + model.name = "name_value" + model.display_name = "display_name_value" + model.type_ = "type__value" + + request = retail_v2beta.UpdateModelRequest( + model=model, + ) + + # Make the request + response = client.update_model(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ModelService_UpdateModel_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_async.py new file mode 100644 index 00000000..6fce3860 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Predict +# 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-retail + + +# [START retail_v2beta_generated_PredictionService_Predict_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 retail_v2beta + + +async def sample_predict(): + # Create a client + client = retail_v2beta.PredictionServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = await client.predict(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_PredictionService_Predict_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_sync.py new file mode 100644 index 00000000..ac2ea94e --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_prediction_service_predict_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Predict +# 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-retail + + +# [START retail_v2beta_generated_PredictionService_Predict_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 retail_v2beta + + +def sample_predict(): + # Create a client + client = retail_v2beta.PredictionServiceClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.PredictRequest( + placement="placement_value", + user_event=user_event, + ) + + # Make the request + response = client.predict(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_PredictionService_Predict_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_async.py new file mode 100644 index 00000000..956a216c --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 AddFulfillmentPlaces +# 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-retail + + +# [START retail_v2beta_generated_ProductService_AddFulfillmentPlaces_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 retail_v2beta + + +async def sample_add_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_AddFulfillmentPlaces_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_sync.py new file mode 100644 index 00000000..89fc672b --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_fulfillment_places_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 AddFulfillmentPlaces +# 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-retail + + +# [START retail_v2beta_generated_ProductService_AddFulfillmentPlaces_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 retail_v2beta + + +def sample_add_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.AddFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.add_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_AddFulfillmentPlaces_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_async.py new file mode 100644 index 00000000..5d3b074d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_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 AddLocalInventories +# 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-retail + + +# [START retail_v2beta_generated_ProductService_AddLocalInventories_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 retail_v2beta + + +async def sample_add_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_AddLocalInventories_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_sync.py new file mode 100644 index 00000000..8cd8c72e --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_add_local_inventories_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 AddLocalInventories +# 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-retail + + +# [START retail_v2beta_generated_ProductService_AddLocalInventories_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 retail_v2beta + + +def sample_add_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.AddLocalInventoriesRequest( + product="product_value", + ) + + # Make the request + operation = client.add_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_AddLocalInventories_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_async.py new file mode 100644 index 00000000..c2a3501c --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +async def sample_create_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = await client.create_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_CreateProduct_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_sync.py new file mode 100644 index 00000000..ba10c031 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_create_product_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +def sample_create_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.CreateProductRequest( + parent="parent_value", + product=product, + product_id="product_id_value", + ) + + # Make the request + response = client.create_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_CreateProduct_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_delete_product_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_delete_product_async.py new file mode 100644 index 00000000..aba83654 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +async def sample_delete_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteProductRequest( + name="name_value", + ) + + # Make the request + await client.delete_product(request=request) + + +# [END retail_v2beta_generated_ProductService_DeleteProduct_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_delete_product_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_delete_product_sync.py new file mode 100644 index 00000000..bc5343d4 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +def sample_delete_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteProductRequest( + name="name_value", + ) + + # Make the request + client.delete_product(request=request) + + +# [END retail_v2beta_generated_ProductService_DeleteProduct_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_get_product_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_get_product_async.py new file mode 100644 index 00000000..308ebe58 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +async def sample_get_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetProductRequest( + name="name_value", + ) + + # Make the request + response = await client.get_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_GetProduct_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_get_product_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_get_product_sync.py new file mode 100644 index 00000000..cb276a67 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +def sample_get_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetProductRequest( + name="name_value", + ) + + # Make the request + response = client.get_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_GetProduct_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_async.py new file mode 100644 index 00000000..451f98fb --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_async.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportProducts +# 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-retail + + +# [START retail_v2beta_generated_ProductService_ImportProducts_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 retail_v2beta + + +async def sample_import_products(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2beta.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2beta.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_ImportProducts_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_sync.py new file mode 100644 index 00000000..0fcfa4d5 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_import_products_sync.py @@ -0,0 +1,60 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportProducts +# 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-retail + + +# [START retail_v2beta_generated_ProductService_ImportProducts_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 retail_v2beta + + +def sample_import_products(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + input_config = retail_v2beta.ProductInputConfig() + input_config.product_inline_source.products.title = "title_value" + + request = retail_v2beta.ImportProductsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_products(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_ImportProducts_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_list_products_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_list_products_async.py new file mode 100644 index 00000000..6e6ac589 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +async def sample_list_products(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.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 retail_v2beta_generated_ProductService_ListProducts_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_list_products_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_list_products_sync.py new file mode 100644 index 00000000..ece91686 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +def sample_list_products(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.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 retail_v2beta_generated_ProductService_ListProducts_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_async.py new file mode 100644 index 00000000..194923ee --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveFulfillmentPlaces +# 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-retail + + +# [START retail_v2beta_generated_ProductService_RemoveFulfillmentPlaces_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 retail_v2beta + + +async def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_RemoveFulfillmentPlaces_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_sync.py new file mode 100644 index 00000000..2cd15f6d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_fulfillment_places_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveFulfillmentPlaces +# 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-retail + + +# [START retail_v2beta_generated_ProductService_RemoveFulfillmentPlaces_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 retail_v2beta + + +def sample_remove_fulfillment_places(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveFulfillmentPlacesRequest( + product="product_value", + type_="type__value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_fulfillment_places(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_RemoveFulfillmentPlaces_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_async.py new file mode 100644 index 00000000..72545609 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveLocalInventories +# 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-retail + + +# [START retail_v2beta_generated_ProductService_RemoveLocalInventories_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 retail_v2beta + + +async def sample_remove_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_RemoveLocalInventories_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_sync.py new file mode 100644 index 00000000..2e21500c --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_remove_local_inventories_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 RemoveLocalInventories +# 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-retail + + +# [START retail_v2beta_generated_ProductService_RemoveLocalInventories_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 retail_v2beta + + +def sample_remove_local_inventories(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveLocalInventoriesRequest( + product="product_value", + place_ids=['place_ids_value1', 'place_ids_value2'], + ) + + # Make the request + operation = client.remove_local_inventories(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_RemoveLocalInventories_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_async.py new file mode 100644 index 00000000..90b25a44 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_async.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetInventory +# 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-retail + + +# [START retail_v2beta_generated_ProductService_SetInventory_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 retail_v2beta + + +async def sample_set_inventory(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + inventory = retail_v2beta.Product() + inventory.title = "title_value" + + request = retail_v2beta.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_SetInventory_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_sync.py new file mode 100644 index 00000000..bac7c186 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_set_inventory_sync.py @@ -0,0 +1,59 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 SetInventory +# 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-retail + + +# [START retail_v2beta_generated_ProductService_SetInventory_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 retail_v2beta + + +def sample_set_inventory(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + inventory = retail_v2beta.Product() + inventory.title = "title_value" + + request = retail_v2beta.SetInventoryRequest( + inventory=inventory, + ) + + # Make the request + operation = client.set_inventory(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_SetInventory_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_async.py new file mode 100644 index 00000000..e0a79ec0 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_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 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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +async def sample_update_product(): + # Create a client + client = retail_v2beta.ProductServiceAsyncClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.UpdateProductRequest( + product=product, + ) + + # Make the request + response = await client.update_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_UpdateProduct_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_sync.py new file mode 100644 index 00000000..3a7a7228 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_product_service_update_product_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 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-retail + + +# [START retail_v2beta_generated_ProductService_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 retail_v2beta + + +def sample_update_product(): + # Create a client + client = retail_v2beta.ProductServiceClient() + + # Initialize request argument(s) + product = retail_v2beta.Product() + product.title = "title_value" + + request = retail_v2beta.UpdateProductRequest( + product=product, + ) + + # Make the request + response = client.update_product(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ProductService_UpdateProduct_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_async.py new file mode 100644 index 00000000..d36307eb --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Search +# 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-retail + + +# [START retail_v2beta_generated_SearchService_Search_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 retail_v2beta + + +async def sample_search(): + # Create a client + client = retail_v2beta.SearchServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2beta_generated_SearchService_Search_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_sync.py new file mode 100644 index 00000000..33c32de9 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_search_service_search_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 Search +# 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-retail + + +# [START retail_v2beta_generated_SearchService_Search_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 retail_v2beta + + +def sample_search(): + # Create a client + client = retail_v2beta.SearchServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.SearchRequest( + placement="placement_value", + visitor_id="visitor_id_value", + ) + + # Make the request + page_result = client.search(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2beta_generated_SearchService_Search_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_async.py new file mode 100644 index 00000000..47f5b06a --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_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 AddControl +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_AddControl_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 retail_v2beta + + +async def sample_add_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.add_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_AddControl_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_sync.py new file mode 100644 index 00000000..b4a0e9f9 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_add_control_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 AddControl +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_AddControl_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 retail_v2beta + + +def sample_add_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.AddControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.add_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_AddControl_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_async.py new file mode 100644 index 00000000..1d046caf --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_async.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_CreateServingConfig_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 retail_v2beta + + +async def sample_create_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = await client.create_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_CreateServingConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_sync.py new file mode 100644 index 00000000..88298bcc --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_create_serving_config_sync.py @@ -0,0 +1,58 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CreateServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_CreateServingConfig_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 retail_v2beta + + +def sample_create_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.CreateServingConfigRequest( + parent="parent_value", + serving_config=serving_config, + serving_config_id="serving_config_id_value", + ) + + # Make the request + response = client.create_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_CreateServingConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_async.py new file mode 100644 index 00000000..40f0d98d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_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 DeleteServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_DeleteServingConfig_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 retail_v2beta + + +async def sample_delete_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + await client.delete_serving_config(request=request) + + +# [END retail_v2beta_generated_ServingConfigService_DeleteServingConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_sync.py new file mode 100644 index 00000000..b30b61fa --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_delete_serving_config_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 DeleteServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_DeleteServingConfig_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 retail_v2beta + + +def sample_delete_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.DeleteServingConfigRequest( + name="name_value", + ) + + # Make the request + client.delete_serving_config(request=request) + + +# [END retail_v2beta_generated_ServingConfigService_DeleteServingConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_async.py new file mode 100644 index 00000000..ec268bcd --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_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 GetServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_GetServingConfig_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 retail_v2beta + + +async def sample_get_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = await client.get_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_GetServingConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_sync.py new file mode 100644 index 00000000..faae2469 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_get_serving_config_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 GetServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_GetServingConfig_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 retail_v2beta + + +def sample_get_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.GetServingConfigRequest( + name="name_value", + ) + + # Make the request + response = client.get_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_GetServingConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_async.py new file mode 100644 index 00000000..8463865d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_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 ListServingConfigs +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_ListServingConfigs_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 retail_v2beta + + +async def sample_list_serving_configs(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + async for response in page_result: + print(response) + +# [END retail_v2beta_generated_ServingConfigService_ListServingConfigs_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_sync.py new file mode 100644 index 00000000..3733c70c --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_list_serving_configs_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 ListServingConfigs +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_ListServingConfigs_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 retail_v2beta + + +def sample_list_serving_configs(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.ListServingConfigsRequest( + parent="parent_value", + ) + + # Make the request + page_result = client.list_serving_configs(request=request) + + # Handle the response + for response in page_result: + print(response) + +# [END retail_v2beta_generated_ServingConfigService_ListServingConfigs_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_async.py new file mode 100644 index 00000000..d60388ae --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_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 RemoveControl +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_RemoveControl_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 retail_v2beta + + +async def sample_remove_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = await client.remove_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_RemoveControl_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_sync.py new file mode 100644 index 00000000..6e339c06 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_remove_control_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 RemoveControl +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_RemoveControl_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 retail_v2beta + + +def sample_remove_control(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RemoveControlRequest( + serving_config="serving_config_value", + control_id="control_id_value", + ) + + # Make the request + response = client.remove_control(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_RemoveControl_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_async.py new file mode 100644 index 00000000..af538ca3 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_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 UpdateServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_UpdateServingConfig_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 retail_v2beta + + +async def sample_update_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceAsyncClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = await client.update_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_UpdateServingConfig_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_sync.py new file mode 100644 index 00000000..27f8003e --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_serving_config_service_update_serving_config_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 UpdateServingConfig +# 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-retail + + +# [START retail_v2beta_generated_ServingConfigService_UpdateServingConfig_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 retail_v2beta + + +def sample_update_serving_config(): + # Create a client + client = retail_v2beta.ServingConfigServiceClient() + + # Initialize request argument(s) + serving_config = retail_v2beta.ServingConfig() + serving_config.display_name = "display_name_value" + serving_config.solution_types = ['SOLUTION_TYPE_SEARCH'] + + request = retail_v2beta.UpdateServingConfigRequest( + serving_config=serving_config, + ) + + # Make the request + response = client.update_serving_config(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_ServingConfigService_UpdateServingConfig_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_async.py new file mode 100644 index 00000000..a6d9e49d --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_async.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CollectUserEvent +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_CollectUserEvent_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 retail_v2beta + + +async def sample_collect_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = await client.collect_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_CollectUserEvent_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_sync.py new file mode 100644 index 00000000..1a8e63d9 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_collect_user_event_sync.py @@ -0,0 +1,54 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 CollectUserEvent +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_CollectUserEvent_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 retail_v2beta + + +def sample_collect_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.CollectUserEventRequest( + prebuilt_rule="prebuilt_rule_value", + parent="parent_value", + user_event="user_event_value", + ) + + # Make the request + response = client.collect_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_CollectUserEvent_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_async.py new file mode 100644 index 00000000..86b50fd3 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_async.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportUserEvents +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_ImportUserEvents_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 retail_v2beta + + +async def sample_import_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + input_config = retail_v2beta.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2beta.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_ImportUserEvents_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_sync.py new file mode 100644 index 00000000..bf2af8ba --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_import_user_events_sync.py @@ -0,0 +1,61 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 ImportUserEvents +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_ImportUserEvents_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 retail_v2beta + + +def sample_import_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + input_config = retail_v2beta.UserEventInputConfig() + input_config.user_event_inline_source.user_events.event_type = "event_type_value" + input_config.user_event_inline_source.user_events.visitor_id = "visitor_id_value" + + request = retail_v2beta.ImportUserEventsRequest( + parent="parent_value", + input_config=input_config, + ) + + # Make the request + operation = client.import_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_ImportUserEvents_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_async.py new file mode 100644 index 00000000..d3113017 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 PurgeUserEvents +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_PurgeUserEvents_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 retail_v2beta + + +async def sample_purge_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_PurgeUserEvents_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_sync.py new file mode 100644 index 00000000..76ef1fa2 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_purge_user_events_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 PurgeUserEvents +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_PurgeUserEvents_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 retail_v2beta + + +def sample_purge_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.PurgeUserEventsRequest( + parent="parent_value", + filter="filter_value", + ) + + # Make the request + operation = client.purge_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_PurgeUserEvents_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_async.py new file mode 100644 index 00000000..f81e1714 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_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 RejoinUserEvents +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_RejoinUserEvents_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 retail_v2beta + + +async def sample_rejoin_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + request = retail_v2beta.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = (await operation).result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_RejoinUserEvents_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_sync.py new file mode 100644 index 00000000..441f599b --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_rejoin_user_events_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 RejoinUserEvents +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_RejoinUserEvents_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 retail_v2beta + + +def sample_rejoin_user_events(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + request = retail_v2beta.RejoinUserEventsRequest( + parent="parent_value", + ) + + # Make the request + operation = client.rejoin_user_events(request=request) + + print("Waiting for operation to complete...") + + response = operation.result() + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_RejoinUserEvents_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_async.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_async.py new file mode 100644 index 00000000..6c415585 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_async.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 WriteUserEvent +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_WriteUserEvent_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 retail_v2beta + + +async def sample_write_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceAsyncClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = await client.write_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_WriteUserEvent_async] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_sync.py b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_sync.py new file mode 100644 index 00000000..4bf66c27 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/retail_v2beta_generated_user_event_service_write_user_event_sync.py @@ -0,0 +1,57 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 WriteUserEvent +# 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-retail + + +# [START retail_v2beta_generated_UserEventService_WriteUserEvent_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 retail_v2beta + + +def sample_write_user_event(): + # Create a client + client = retail_v2beta.UserEventServiceClient() + + # Initialize request argument(s) + user_event = retail_v2beta.UserEvent() + user_event.event_type = "event_type_value" + user_event.visitor_id = "visitor_id_value" + + request = retail_v2beta.WriteUserEventRequest( + parent="parent_value", + user_event=user_event, + ) + + # Make the request + response = client.write_user_event(request=request) + + # Handle the response + print(response) + +# [END retail_v2beta_generated_UserEventService_WriteUserEvent_sync] diff --git a/owl-bot-staging/v2beta/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json b/owl-bot-staging/v2beta/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json new file mode 100644 index 00000000..edada0c1 --- /dev/null +++ b/owl-bot-staging/v2beta/samples/generated_samples/snippet_metadata_google.cloud.retail.v2beta.json @@ -0,0 +1,8365 @@ +{ + "clientLibrary": { + "apis": [ + { + "id": "google.cloud.retail.v2beta", + "version": "v2beta" + } + ], + "language": "PYTHON", + "name": "google-cloud-retail", + "version": "0.1.0" + }, + "snippets": [ + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.add_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "AddCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.AttributesConfig", + "shortName": "add_catalog_attribute" + }, + "description": "Sample for AddCatalogAttribute", + "file": "retail_v2beta_generated_catalog_service_add_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_AddCatalogAttribute_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": "retail_v2beta_generated_catalog_service_add_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.add_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.AddCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "AddCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.AttributesConfig", + "shortName": "add_catalog_attribute" + }, + "description": "Sample for AddCatalogAttribute", + "file": "retail_v2beta_generated_catalog_service_add_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_AddCatalogAttribute_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": "retail_v2beta_generated_catalog_service_add_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.batch_remove_catalog_attributes", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "BatchRemoveCatalogAttributes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesResponse", + "shortName": "batch_remove_catalog_attributes" + }, + "description": "Sample for BatchRemoveCatalogAttributes", + "file": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.batch_remove_catalog_attributes", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.BatchRemoveCatalogAttributes", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "BatchRemoveCatalogAttributes" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.BatchRemoveCatalogAttributesResponse", + "shortName": "batch_remove_catalog_attributes" + }, + "description": "Sample for BatchRemoveCatalogAttributes", + "file": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_BatchRemoveCatalogAttributes_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_batch_remove_catalog_attributes_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.get_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.GetAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetAttributesConfigRequest" + }, + { + "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.retail_v2beta.types.AttributesConfig", + "shortName": "get_attributes_config" + }, + "description": "Sample for GetAttributesConfig", + "file": "retail_v2beta_generated_catalog_service_get_attributes_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_GetAttributesConfig_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": "retail_v2beta_generated_catalog_service_get_attributes_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.get_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.GetAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetAttributesConfigRequest" + }, + { + "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.retail_v2beta.types.AttributesConfig", + "shortName": "get_attributes_config" + }, + "description": "Sample for GetAttributesConfig", + "file": "retail_v2beta_generated_catalog_service_get_attributes_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_GetAttributesConfig_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": "retail_v2beta_generated_catalog_service_get_attributes_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.get_completion_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.GetCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetCompletionConfigRequest" + }, + { + "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.retail_v2beta.types.CompletionConfig", + "shortName": "get_completion_config" + }, + "description": "Sample for GetCompletionConfig", + "file": "retail_v2beta_generated_catalog_service_get_completion_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_GetCompletionConfig_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": "retail_v2beta_generated_catalog_service_get_completion_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.get_completion_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.GetCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetCompletionConfigRequest" + }, + { + "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.retail_v2beta.types.CompletionConfig", + "shortName": "get_completion_config" + }, + "description": "Sample for GetCompletionConfig", + "file": "retail_v2beta_generated_catalog_service_get_completion_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_GetCompletionConfig_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": "retail_v2beta_generated_catalog_service_get_completion_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.get_default_branch", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.GetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.GetDefaultBranchResponse", + "shortName": "get_default_branch" + }, + "description": "Sample for GetDefaultBranch", + "file": "retail_v2beta_generated_catalog_service_get_default_branch_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_GetDefaultBranch_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": "retail_v2beta_generated_catalog_service_get_default_branch_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.get_default_branch", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.GetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "GetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.GetDefaultBranchResponse", + "shortName": "get_default_branch" + }, + "description": "Sample for GetDefaultBranch", + "file": "retail_v2beta_generated_catalog_service_get_default_branch_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_GetDefaultBranch_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": "retail_v2beta_generated_catalog_service_get_default_branch_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.list_catalogs", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.ListCatalogs", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ListCatalogs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListCatalogsRequest" + }, + { + "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.retail_v2beta.services.catalog_service.pagers.ListCatalogsAsyncPager", + "shortName": "list_catalogs" + }, + "description": "Sample for ListCatalogs", + "file": "retail_v2beta_generated_catalog_service_list_catalogs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_ListCatalogs_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": "retail_v2beta_generated_catalog_service_list_catalogs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.list_catalogs", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.ListCatalogs", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ListCatalogs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListCatalogsRequest" + }, + { + "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.retail_v2beta.services.catalog_service.pagers.ListCatalogsPager", + "shortName": "list_catalogs" + }, + "description": "Sample for ListCatalogs", + "file": "retail_v2beta_generated_catalog_service_list_catalogs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_ListCatalogs_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": "retail_v2beta_generated_catalog_service_list_catalogs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.remove_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.RemoveCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "RemoveCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.AttributesConfig", + "shortName": "remove_catalog_attribute" + }, + "description": "Sample for RemoveCatalogAttribute", + "file": "retail_v2beta_generated_catalog_service_remove_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_RemoveCatalogAttribute_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_remove_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.remove_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.RemoveCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "RemoveCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.AttributesConfig", + "shortName": "remove_catalog_attribute" + }, + "description": "Sample for RemoveCatalogAttribute", + "file": "retail_v2beta_generated_catalog_service_remove_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_RemoveCatalogAttribute_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_remove_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.replace_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ReplaceCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ReplaceCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.AttributesConfig", + "shortName": "replace_catalog_attribute" + }, + "description": "Sample for ReplaceCatalogAttribute", + "file": "retail_v2beta_generated_catalog_service_replace_catalog_attribute_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_ReplaceCatalogAttribute_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": "retail_v2beta_generated_catalog_service_replace_catalog_attribute_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.replace_catalog_attribute", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.ReplaceCatalogAttribute", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "ReplaceCatalogAttribute" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ReplaceCatalogAttributeRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.AttributesConfig", + "shortName": "replace_catalog_attribute" + }, + "description": "Sample for ReplaceCatalogAttribute", + "file": "retail_v2beta_generated_catalog_service_replace_catalog_attribute_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_ReplaceCatalogAttribute_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": "retail_v2beta_generated_catalog_service_replace_catalog_attribute_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.set_default_branch", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.SetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "SetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.SetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "set_default_branch" + }, + "description": "Sample for SetDefaultBranch", + "file": "retail_v2beta_generated_catalog_service_set_default_branch_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_SetDefaultBranch_async", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_set_default_branch_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.set_default_branch", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.SetDefaultBranch", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "SetDefaultBranch" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.SetDefaultBranchRequest" + }, + { + "name": "catalog", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "shortName": "set_default_branch" + }, + "description": "Sample for SetDefaultBranch", + "file": "retail_v2beta_generated_catalog_service_set_default_branch_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_SetDefaultBranch_sync", + "segments": [ + { + "end": 48, + "start": 27, + "type": "FULL" + }, + { + "end": 48, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 44, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "start": 45, + "type": "REQUEST_EXECUTION" + }, + { + "end": 49, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_set_default_branch_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.update_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateAttributesConfigRequest" + }, + { + "name": "attributes_config", + "type": "google.cloud.retail_v2beta.types.AttributesConfig" + }, + { + "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.retail_v2beta.types.AttributesConfig", + "shortName": "update_attributes_config" + }, + "description": "Sample for UpdateAttributesConfig", + "file": "retail_v2beta_generated_catalog_service_update_attributes_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_UpdateAttributesConfig_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_update_attributes_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.update_attributes_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.UpdateAttributesConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateAttributesConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateAttributesConfigRequest" + }, + { + "name": "attributes_config", + "type": "google.cloud.retail_v2beta.types.AttributesConfig" + }, + { + "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.retail_v2beta.types.AttributesConfig", + "shortName": "update_attributes_config" + }, + "description": "Sample for UpdateAttributesConfig", + "file": "retail_v2beta_generated_catalog_service_update_attributes_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_UpdateAttributesConfig_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_update_attributes_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.update_catalog", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.UpdateCatalog", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCatalog" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateCatalogRequest" + }, + { + "name": "catalog", + "type": "google.cloud.retail_v2beta.types.Catalog" + }, + { + "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.retail_v2beta.types.Catalog", + "shortName": "update_catalog" + }, + "description": "Sample for UpdateCatalog", + "file": "retail_v2beta_generated_catalog_service_update_catalog_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_UpdateCatalog_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": "retail_v2beta_generated_catalog_service_update_catalog_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.update_catalog", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.UpdateCatalog", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCatalog" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateCatalogRequest" + }, + { + "name": "catalog", + "type": "google.cloud.retail_v2beta.types.Catalog" + }, + { + "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.retail_v2beta.types.Catalog", + "shortName": "update_catalog" + }, + "description": "Sample for UpdateCatalog", + "file": "retail_v2beta_generated_catalog_service_update_catalog_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_UpdateCatalog_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": "retail_v2beta_generated_catalog_service_update_catalog_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient", + "shortName": "CatalogServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceAsyncClient.update_completion_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.UpdateCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateCompletionConfigRequest" + }, + { + "name": "completion_config", + "type": "google.cloud.retail_v2beta.types.CompletionConfig" + }, + { + "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.retail_v2beta.types.CompletionConfig", + "shortName": "update_completion_config" + }, + "description": "Sample for UpdateCompletionConfig", + "file": "retail_v2beta_generated_catalog_service_update_completion_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_UpdateCompletionConfig_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_update_completion_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient", + "shortName": "CatalogServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CatalogServiceClient.update_completion_config", + "method": { + "fullName": "google.cloud.retail.v2beta.CatalogService.UpdateCompletionConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.CatalogService", + "shortName": "CatalogService" + }, + "shortName": "UpdateCompletionConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateCompletionConfigRequest" + }, + { + "name": "completion_config", + "type": "google.cloud.retail_v2beta.types.CompletionConfig" + }, + { + "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.retail_v2beta.types.CompletionConfig", + "shortName": "update_completion_config" + }, + "description": "Sample for UpdateCompletionConfig", + "file": "retail_v2beta_generated_catalog_service_update_completion_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CatalogService_UpdateCompletionConfig_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_catalog_service_update_completion_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CompletionServiceAsyncClient", + "shortName": "CompletionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CompletionServiceAsyncClient.complete_query", + "method": { + "fullName": "google.cloud.retail.v2beta.CompletionService.CompleteQuery", + "service": { + "fullName": "google.cloud.retail.v2beta.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "CompleteQuery" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CompleteQueryRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.CompleteQueryResponse", + "shortName": "complete_query" + }, + "description": "Sample for CompleteQuery", + "file": "retail_v2beta_generated_completion_service_complete_query_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CompletionService_CompleteQuery_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_completion_service_complete_query_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CompletionServiceClient", + "shortName": "CompletionServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CompletionServiceClient.complete_query", + "method": { + "fullName": "google.cloud.retail.v2beta.CompletionService.CompleteQuery", + "service": { + "fullName": "google.cloud.retail.v2beta.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "CompleteQuery" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CompleteQueryRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.CompleteQueryResponse", + "shortName": "complete_query" + }, + "description": "Sample for CompleteQuery", + "file": "retail_v2beta_generated_completion_service_complete_query_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CompletionService_CompleteQuery_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_completion_service_complete_query_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.CompletionServiceAsyncClient", + "shortName": "CompletionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.CompletionServiceAsyncClient.import_completion_data", + "method": { + "fullName": "google.cloud.retail.v2beta.CompletionService.ImportCompletionData", + "service": { + "fullName": "google.cloud.retail.v2beta.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "ImportCompletionData" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ImportCompletionDataRequest" + }, + { + "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_completion_data" + }, + "description": "Sample for ImportCompletionData", + "file": "retail_v2beta_generated_completion_service_import_completion_data_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CompletionService_ImportCompletionData_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_completion_service_import_completion_data_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.CompletionServiceClient", + "shortName": "CompletionServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.CompletionServiceClient.import_completion_data", + "method": { + "fullName": "google.cloud.retail.v2beta.CompletionService.ImportCompletionData", + "service": { + "fullName": "google.cloud.retail.v2beta.CompletionService", + "shortName": "CompletionService" + }, + "shortName": "ImportCompletionData" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ImportCompletionDataRequest" + }, + { + "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_completion_data" + }, + "description": "Sample for ImportCompletionData", + "file": "retail_v2beta_generated_completion_service_import_completion_data_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_CompletionService_ImportCompletionData_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_completion_service_import_completion_data_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient.create_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.CreateControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "CreateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateControlRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "control", + "type": "google.cloud.retail_v2beta.types.Control" + }, + { + "name": "control_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.retail_v2beta.types.Control", + "shortName": "create_control" + }, + "description": "Sample for CreateControl", + "file": "retail_v2beta_generated_control_service_create_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_CreateControl_async", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 52, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 53, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_control_service_create_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceClient.create_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.CreateControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "CreateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateControlRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "control", + "type": "google.cloud.retail_v2beta.types.Control" + }, + { + "name": "control_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.retail_v2beta.types.Control", + "shortName": "create_control" + }, + "description": "Sample for CreateControl", + "file": "retail_v2beta_generated_control_service_create_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_CreateControl_sync", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 52, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 53, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_control_service_create_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient.delete_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.DeleteControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "DeleteControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.DeleteControlRequest" + }, + { + "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_control" + }, + "description": "Sample for DeleteControl", + "file": "retail_v2beta_generated_control_service_delete_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_DeleteControl_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": "retail_v2beta_generated_control_service_delete_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceClient.delete_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.DeleteControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "DeleteControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.DeleteControlRequest" + }, + { + "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_control" + }, + "description": "Sample for DeleteControl", + "file": "retail_v2beta_generated_control_service_delete_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_DeleteControl_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": "retail_v2beta_generated_control_service_delete_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient.get_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.GetControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "GetControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetControlRequest" + }, + { + "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.retail_v2beta.types.Control", + "shortName": "get_control" + }, + "description": "Sample for GetControl", + "file": "retail_v2beta_generated_control_service_get_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_GetControl_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": "retail_v2beta_generated_control_service_get_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceClient.get_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.GetControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "GetControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetControlRequest" + }, + { + "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.retail_v2beta.types.Control", + "shortName": "get_control" + }, + "description": "Sample for GetControl", + "file": "retail_v2beta_generated_control_service_get_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_GetControl_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": "retail_v2beta_generated_control_service_get_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient.list_controls", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.ListControls", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "ListControls" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListControlsRequest" + }, + { + "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.retail_v2beta.services.control_service.pagers.ListControlsAsyncPager", + "shortName": "list_controls" + }, + "description": "Sample for ListControls", + "file": "retail_v2beta_generated_control_service_list_controls_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_ListControls_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": "retail_v2beta_generated_control_service_list_controls_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceClient.list_controls", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.ListControls", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "ListControls" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListControlsRequest" + }, + { + "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.retail_v2beta.services.control_service.pagers.ListControlsPager", + "shortName": "list_controls" + }, + "description": "Sample for ListControls", + "file": "retail_v2beta_generated_control_service_list_controls_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_ListControls_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": "retail_v2beta_generated_control_service_list_controls_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient", + "shortName": "ControlServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceAsyncClient.update_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.UpdateControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "UpdateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateControlRequest" + }, + { + "name": "control", + "type": "google.cloud.retail_v2beta.types.Control" + }, + { + "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.retail_v2beta.types.Control", + "shortName": "update_control" + }, + "description": "Sample for UpdateControl", + "file": "retail_v2beta_generated_control_service_update_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_UpdateControl_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_control_service_update_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ControlServiceClient", + "shortName": "ControlServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ControlServiceClient.update_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ControlService.UpdateControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ControlService", + "shortName": "ControlService" + }, + "shortName": "UpdateControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateControlRequest" + }, + { + "name": "control", + "type": "google.cloud.retail_v2beta.types.Control" + }, + { + "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.retail_v2beta.types.Control", + "shortName": "update_control" + }, + "description": "Sample for UpdateControl", + "file": "retail_v2beta_generated_control_service_update_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ControlService_UpdateControl_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_control_service_update_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.types.Model" + }, + { + "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": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2beta_generated_model_service_create_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_CreateModel_async", + "segments": [ + { + "end": 61, + "start": 27, + "type": "FULL" + }, + { + "end": 61, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 58, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 62, + "start": 59, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_create_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.create_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.CreateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "CreateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateModelRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.types.Model" + }, + { + "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": "create_model" + }, + "description": "Sample for CreateModel", + "file": "retail_v2beta_generated_model_service_create_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_CreateModel_sync", + "segments": [ + { + "end": 61, + "start": 27, + "type": "FULL" + }, + { + "end": 61, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 58, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 62, + "start": 59, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_create_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.DeleteModelRequest" + }, + { + "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_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2beta_generated_model_service_delete_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_DeleteModel_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": "retail_v2beta_generated_model_service_delete_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.delete_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.DeleteModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "DeleteModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.DeleteModelRequest" + }, + { + "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_model" + }, + "description": "Sample for DeleteModel", + "file": "retail_v2beta_generated_model_service_delete_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_DeleteModel_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": "retail_v2beta_generated_model_service_delete_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetModelRequest" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2beta_generated_model_service_get_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_GetModel_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": "retail_v2beta_generated_model_service_get_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.get_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.GetModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "GetModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetModelRequest" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "get_model" + }, + "description": "Sample for GetModel", + "file": "retail_v2beta_generated_model_service_get_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_GetModel_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": "retail_v2beta_generated_model_service_get_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListModelsRequest" + }, + { + "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.retail_v2beta.services.model_service.pagers.ListModelsAsyncPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2beta_generated_model_service_list_models_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ListModels_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": "retail_v2beta_generated_model_service_list_models_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.list_models", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ListModels", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ListModels" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListModelsRequest" + }, + { + "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.retail_v2beta.services.model_service.pagers.ListModelsPager", + "shortName": "list_models" + }, + "description": "Sample for ListModels", + "file": "retail_v2beta_generated_model_service_list_models_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ListModels_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": "retail_v2beta_generated_model_service_list_models_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.PauseModelRequest" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2beta_generated_model_service_pause_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_PauseModel_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": "retail_v2beta_generated_model_service_pause_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.pause_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.PauseModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "PauseModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.PauseModelRequest" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "pause_model" + }, + "description": "Sample for PauseModel", + "file": "retail_v2beta_generated_model_service_pause_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_PauseModel_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": "retail_v2beta_generated_model_service_pause_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ResumeModelRequest" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2beta_generated_model_service_resume_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ResumeModel_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": "retail_v2beta_generated_model_service_resume_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.resume_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.ResumeModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "ResumeModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ResumeModelRequest" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "resume_model" + }, + "description": "Sample for ResumeModel", + "file": "retail_v2beta_generated_model_service_resume_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_ResumeModel_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": "retail_v2beta_generated_model_service_resume_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.TuneModelRequest" + }, + { + "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.api_core.operation_async.AsyncOperation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2beta_generated_model_service_tune_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_TuneModel_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": "retail_v2beta_generated_model_service_tune_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.tune_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.TuneModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "TuneModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.TuneModelRequest" + }, + { + "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.api_core.operation.Operation", + "shortName": "tune_model" + }, + "description": "Sample for TuneModel", + "file": "retail_v2beta_generated_model_service_tune_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_TuneModel_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": "retail_v2beta_generated_model_service_tune_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient", + "shortName": "ModelServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceAsyncClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.types.Model" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2beta_generated_model_service_update_model_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_UpdateModel_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_update_model_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ModelServiceClient", + "shortName": "ModelServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ModelServiceClient.update_model", + "method": { + "fullName": "google.cloud.retail.v2beta.ModelService.UpdateModel", + "service": { + "fullName": "google.cloud.retail.v2beta.ModelService", + "shortName": "ModelService" + }, + "shortName": "UpdateModel" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateModelRequest" + }, + { + "name": "model", + "type": "google.cloud.retail_v2beta.types.Model" + }, + { + "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.retail_v2beta.types.Model", + "shortName": "update_model" + }, + "description": "Sample for UpdateModel", + "file": "retail_v2beta_generated_model_service_update_model_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ModelService_UpdateModel_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_model_service_update_model_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.PredictionServiceAsyncClient", + "shortName": "PredictionServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.PredictionServiceAsyncClient.predict", + "method": { + "fullName": "google.cloud.retail.v2beta.PredictionService.Predict", + "service": { + "fullName": "google.cloud.retail.v2beta.PredictionService", + "shortName": "PredictionService" + }, + "shortName": "Predict" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.PredictRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.PredictResponse", + "shortName": "predict" + }, + "description": "Sample for Predict", + "file": "retail_v2beta_generated_prediction_service_predict_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_PredictionService_Predict_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_prediction_service_predict_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.PredictionServiceClient", + "shortName": "PredictionServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.PredictionServiceClient.predict", + "method": { + "fullName": "google.cloud.retail.v2beta.PredictionService.Predict", + "service": { + "fullName": "google.cloud.retail.v2beta.PredictionService", + "shortName": "PredictionService" + }, + "shortName": "Predict" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.PredictRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.PredictResponse", + "shortName": "predict" + }, + "description": "Sample for Predict", + "file": "retail_v2beta_generated_prediction_service_predict_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_PredictionService_Predict_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_prediction_service_predict_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.add_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "add_fulfillment_places" + }, + "description": "Sample for AddFulfillmentPlaces", + "file": "retail_v2beta_generated_product_service_add_fulfillment_places_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_AddFulfillmentPlaces_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_add_fulfillment_places_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.add_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.AddFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "add_fulfillment_places" + }, + "description": "Sample for AddFulfillmentPlaces", + "file": "retail_v2beta_generated_product_service_add_fulfillment_places_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_AddFulfillmentPlaces_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_add_fulfillment_places_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.add_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.AddLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddLocalInventoriesRequest" + }, + { + "name": "product", + "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": "add_local_inventories" + }, + "description": "Sample for AddLocalInventories", + "file": "retail_v2beta_generated_product_service_add_local_inventories_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_AddLocalInventories_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": "retail_v2beta_generated_product_service_add_local_inventories_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.add_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.AddLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "AddLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddLocalInventoriesRequest" + }, + { + "name": "product", + "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": "add_local_inventories" + }, + "description": "Sample for AddLocalInventories", + "file": "retail_v2beta_generated_product_service_add_local_inventories_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_AddLocalInventories_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": "retail_v2beta_generated_product_service_add_local_inventories_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.create_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.CreateProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "retail_v2beta_generated_product_service_create_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_CreateProduct_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_create_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.create_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.CreateProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "CreateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateProductRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "product", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.types.Product", + "shortName": "create_product" + }, + "description": "Sample for CreateProduct", + "file": "retail_v2beta_generated_product_service_create_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_CreateProduct_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_create_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.delete_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.DeleteProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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": "retail_v2beta_generated_product_service_delete_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_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": "retail_v2beta_generated_product_service_delete_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.delete_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.DeleteProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "DeleteProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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": "retail_v2beta_generated_product_service_delete_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_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": "retail_v2beta_generated_product_service_delete_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.get_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.GetProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "retail_v2beta_generated_product_service_get_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_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": "retail_v2beta_generated_product_service_get_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.get_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.GetProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "GetProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.types.Product", + "shortName": "get_product" + }, + "description": "Sample for GetProduct", + "file": "retail_v2beta_generated_product_service_get_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_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": "retail_v2beta_generated_product_service_get_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.import_products", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.ImportProducts", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "ImportProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ImportProductsRequest" + }, + { + "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_products" + }, + "description": "Sample for ImportProducts", + "file": "retail_v2beta_generated_product_service_import_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_ImportProducts_async", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_import_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.import_products", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.ImportProducts", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "ImportProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ImportProductsRequest" + }, + { + "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_products" + }, + "description": "Sample for ImportProducts", + "file": "retail_v2beta_generated_product_service_import_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_ImportProducts_sync", + "segments": [ + { + "end": 59, + "start": 27, + "type": "FULL" + }, + { + "end": 59, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 49, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 56, + "start": 50, + "type": "REQUEST_EXECUTION" + }, + { + "end": 60, + "start": 57, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_import_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.list_products", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.ListProducts", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.services.product_service.pagers.ListProductsAsyncPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "retail_v2beta_generated_product_service_list_products_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_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": "retail_v2beta_generated_product_service_list_products_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.list_products", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.ListProducts", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "ListProducts" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.services.product_service.pagers.ListProductsPager", + "shortName": "list_products" + }, + "description": "Sample for ListProducts", + "file": "retail_v2beta_generated_product_service_list_products_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_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": "retail_v2beta_generated_product_service_list_products_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.remove_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "remove_fulfillment_places" + }, + "description": "Sample for RemoveFulfillmentPlaces", + "file": "retail_v2beta_generated_product_service_remove_fulfillment_places_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_RemoveFulfillmentPlaces_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_remove_fulfillment_places_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.remove_fulfillment_places", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.RemoveFulfillmentPlaces", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveFulfillmentPlaces" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveFulfillmentPlacesRequest" + }, + { + "name": "product", + "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": "remove_fulfillment_places" + }, + "description": "Sample for RemoveFulfillmentPlaces", + "file": "retail_v2beta_generated_product_service_remove_fulfillment_places_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_RemoveFulfillmentPlaces_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_remove_fulfillment_places_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.remove_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.RemoveLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveLocalInventoriesRequest" + }, + { + "name": "product", + "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": "remove_local_inventories" + }, + "description": "Sample for RemoveLocalInventories", + "file": "retail_v2beta_generated_product_service_remove_local_inventories_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_RemoveLocalInventories_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_remove_local_inventories_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.remove_local_inventories", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.RemoveLocalInventories", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "RemoveLocalInventories" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveLocalInventoriesRequest" + }, + { + "name": "product", + "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": "remove_local_inventories" + }, + "description": "Sample for RemoveLocalInventories", + "file": "retail_v2beta_generated_product_service_remove_local_inventories_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_RemoveLocalInventories_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_remove_local_inventories_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.set_inventory", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.SetInventory", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "SetInventory" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.SetInventoryRequest" + }, + { + "name": "inventory", + "type": "google.cloud.retail_v2beta.types.Product" + }, + { + "name": "set_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.api_core.operation_async.AsyncOperation", + "shortName": "set_inventory" + }, + "description": "Sample for SetInventory", + "file": "retail_v2beta_generated_product_service_set_inventory_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_SetInventory_async", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_set_inventory_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.set_inventory", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.SetInventory", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "SetInventory" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.SetInventoryRequest" + }, + { + "name": "inventory", + "type": "google.cloud.retail_v2beta.types.Product" + }, + { + "name": "set_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.api_core.operation.Operation", + "shortName": "set_inventory" + }, + "description": "Sample for SetInventory", + "file": "retail_v2beta_generated_product_service_set_inventory_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_SetInventory_sync", + "segments": [ + { + "end": 58, + "start": 27, + "type": "FULL" + }, + { + "end": 58, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 55, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 59, + "start": 56, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_set_inventory_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient", + "shortName": "ProductServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceAsyncClient.update_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.UpdateProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "retail_v2beta_generated_product_service_update_product_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_UpdateProduct_async", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_update_product_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ProductServiceClient", + "shortName": "ProductServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ProductServiceClient.update_product", + "method": { + "fullName": "google.cloud.retail.v2beta.ProductService.UpdateProduct", + "service": { + "fullName": "google.cloud.retail.v2beta.ProductService", + "shortName": "ProductService" + }, + "shortName": "UpdateProduct" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateProductRequest" + }, + { + "name": "product", + "type": "google.cloud.retail_v2beta.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.retail_v2beta.types.Product", + "shortName": "update_product" + }, + "description": "Sample for UpdateProduct", + "file": "retail_v2beta_generated_product_service_update_product_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ProductService_UpdateProduct_sync", + "segments": [ + { + "end": 54, + "start": 27, + "type": "FULL" + }, + { + "end": 54, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 48, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 51, + "start": 49, + "type": "REQUEST_EXECUTION" + }, + { + "end": 55, + "start": 52, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_product_service_update_product_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.SearchServiceAsyncClient", + "shortName": "SearchServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.SearchServiceAsyncClient.search", + "method": { + "fullName": "google.cloud.retail.v2beta.SearchService.Search", + "service": { + "fullName": "google.cloud.retail.v2beta.SearchService", + "shortName": "SearchService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.SearchRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.services.search_service.pagers.SearchAsyncPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "retail_v2beta_generated_search_service_search_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_SearchService_Search_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_search_service_search_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.SearchServiceClient", + "shortName": "SearchServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.SearchServiceClient.search", + "method": { + "fullName": "google.cloud.retail.v2beta.SearchService.Search", + "service": { + "fullName": "google.cloud.retail.v2beta.SearchService", + "shortName": "SearchService" + }, + "shortName": "Search" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.SearchRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.services.search_service.pagers.SearchPager", + "shortName": "search" + }, + "description": "Sample for Search", + "file": "retail_v2beta_generated_search_service_search_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_SearchService_Search_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_search_service_search_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient.add_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.AddControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "AddControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.ServingConfig", + "shortName": "add_control" + }, + "description": "Sample for AddControl", + "file": "retail_v2beta_generated_serving_config_service_add_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_AddControl_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_serving_config_service_add_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient.add_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.AddControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "AddControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.AddControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.ServingConfig", + "shortName": "add_control" + }, + "description": "Sample for AddControl", + "file": "retail_v2beta_generated_serving_config_service_add_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_AddControl_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_serving_config_service_add_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient.create_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.CreateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "CreateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateServingConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2beta.types.ServingConfig" + }, + { + "name": "serving_config_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.retail_v2beta.types.ServingConfig", + "shortName": "create_serving_config" + }, + "description": "Sample for CreateServingConfig", + "file": "retail_v2beta_generated_serving_config_service_create_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_CreateServingConfig_async", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_serving_config_service_create_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient.create_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.CreateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "CreateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CreateServingConfigRequest" + }, + { + "name": "parent", + "type": "str" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2beta.types.ServingConfig" + }, + { + "name": "serving_config_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.retail_v2beta.types.ServingConfig", + "shortName": "create_serving_config" + }, + "description": "Sample for CreateServingConfig", + "file": "retail_v2beta_generated_serving_config_service_create_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_CreateServingConfig_sync", + "segments": [ + { + "end": 57, + "start": 27, + "type": "FULL" + }, + { + "end": 57, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 51, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 54, + "start": 52, + "type": "REQUEST_EXECUTION" + }, + { + "end": 58, + "start": 55, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_serving_config_service_create_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient.delete_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.DeleteServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "DeleteServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.DeleteServingConfigRequest" + }, + { + "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_serving_config" + }, + "description": "Sample for DeleteServingConfig", + "file": "retail_v2beta_generated_serving_config_service_delete_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_DeleteServingConfig_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": "retail_v2beta_generated_serving_config_service_delete_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient.delete_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.DeleteServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "DeleteServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.DeleteServingConfigRequest" + }, + { + "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_serving_config" + }, + "description": "Sample for DeleteServingConfig", + "file": "retail_v2beta_generated_serving_config_service_delete_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_DeleteServingConfig_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": "retail_v2beta_generated_serving_config_service_delete_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient.get_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.GetServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "GetServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetServingConfigRequest" + }, + { + "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.retail_v2beta.types.ServingConfig", + "shortName": "get_serving_config" + }, + "description": "Sample for GetServingConfig", + "file": "retail_v2beta_generated_serving_config_service_get_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_GetServingConfig_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": "retail_v2beta_generated_serving_config_service_get_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient.get_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.GetServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "GetServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.GetServingConfigRequest" + }, + { + "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.retail_v2beta.types.ServingConfig", + "shortName": "get_serving_config" + }, + "description": "Sample for GetServingConfig", + "file": "retail_v2beta_generated_serving_config_service_get_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_GetServingConfig_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": "retail_v2beta_generated_serving_config_service_get_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient.list_serving_configs", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.ListServingConfigs", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "ListServingConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListServingConfigsRequest" + }, + { + "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.retail_v2beta.services.serving_config_service.pagers.ListServingConfigsAsyncPager", + "shortName": "list_serving_configs" + }, + "description": "Sample for ListServingConfigs", + "file": "retail_v2beta_generated_serving_config_service_list_serving_configs_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_ListServingConfigs_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": "retail_v2beta_generated_serving_config_service_list_serving_configs_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient.list_serving_configs", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.ListServingConfigs", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "ListServingConfigs" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ListServingConfigsRequest" + }, + { + "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.retail_v2beta.services.serving_config_service.pagers.ListServingConfigsPager", + "shortName": "list_serving_configs" + }, + "description": "Sample for ListServingConfigs", + "file": "retail_v2beta_generated_serving_config_service_list_serving_configs_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_ListServingConfigs_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": "retail_v2beta_generated_serving_config_service_list_serving_configs_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient.remove_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.RemoveControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "RemoveControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.ServingConfig", + "shortName": "remove_control" + }, + "description": "Sample for RemoveControl", + "file": "retail_v2beta_generated_serving_config_service_remove_control_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_RemoveControl_async", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_serving_config_service_remove_control_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient.remove_control", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.RemoveControl", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "RemoveControl" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RemoveControlRequest" + }, + { + "name": "serving_config", + "type": "str" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.ServingConfig", + "shortName": "remove_control" + }, + "description": "Sample for RemoveControl", + "file": "retail_v2beta_generated_serving_config_service_remove_control_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_RemoveControl_sync", + "segments": [ + { + "end": 52, + "start": 27, + "type": "FULL" + }, + { + "end": 52, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 49, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 53, + "start": 50, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_serving_config_service_remove_control_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient", + "shortName": "ServingConfigServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceAsyncClient.update_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.UpdateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "UpdateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateServingConfigRequest" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2beta.types.ServingConfig" + }, + { + "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.retail_v2beta.types.ServingConfig", + "shortName": "update_serving_config" + }, + "description": "Sample for UpdateServingConfig", + "file": "retail_v2beta_generated_serving_config_service_update_serving_config_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_UpdateServingConfig_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": "retail_v2beta_generated_serving_config_service_update_serving_config_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient", + "shortName": "ServingConfigServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.ServingConfigServiceClient.update_serving_config", + "method": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService.UpdateServingConfig", + "service": { + "fullName": "google.cloud.retail.v2beta.ServingConfigService", + "shortName": "ServingConfigService" + }, + "shortName": "UpdateServingConfig" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.UpdateServingConfigRequest" + }, + { + "name": "serving_config", + "type": "google.cloud.retail_v2beta.types.ServingConfig" + }, + { + "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.retail_v2beta.types.ServingConfig", + "shortName": "update_serving_config" + }, + "description": "Sample for UpdateServingConfig", + "file": "retail_v2beta_generated_serving_config_service_update_serving_config_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_ServingConfigService_UpdateServingConfig_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": "retail_v2beta_generated_serving_config_service_update_serving_config_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient.collect_user_event", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.CollectUserEvent", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "CollectUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CollectUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api.httpbody_pb2.HttpBody", + "shortName": "collect_user_event" + }, + "description": "Sample for CollectUserEvent", + "file": "retail_v2beta_generated_user_event_service_collect_user_event_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_CollectUserEvent_async", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_collect_user_event_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient.collect_user_event", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.CollectUserEvent", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "CollectUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.CollectUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.api.httpbody_pb2.HttpBody", + "shortName": "collect_user_event" + }, + "description": "Sample for CollectUserEvent", + "file": "retail_v2beta_generated_user_event_service_collect_user_event_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_CollectUserEvent_sync", + "segments": [ + { + "end": 53, + "start": 27, + "type": "FULL" + }, + { + "end": 53, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 47, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 50, + "start": 48, + "type": "REQUEST_EXECUTION" + }, + { + "end": 54, + "start": 51, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_collect_user_event_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient.import_user_events", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.ImportUserEvents", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "ImportUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ImportUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for ImportUserEvents", + "file": "retail_v2beta_generated_user_event_service_import_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_ImportUserEvents_async", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_import_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient.import_user_events", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.ImportUserEvents", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "ImportUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.ImportUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for ImportUserEvents", + "file": "retail_v2beta_generated_user_event_service_import_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_ImportUserEvents_sync", + "segments": [ + { + "end": 60, + "start": 27, + "type": "FULL" + }, + { + "end": 60, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 57, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 61, + "start": 58, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_import_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient.purge_user_events", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.PurgeUserEvents", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "PurgeUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.PurgeUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for PurgeUserEvents", + "file": "retail_v2beta_generated_user_event_service_purge_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_PurgeUserEvents_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_purge_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient.purge_user_events", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.PurgeUserEvents", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "PurgeUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.PurgeUserEventsRequest" + }, + { + "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_user_events" + }, + "description": "Sample for PurgeUserEvents", + "file": "retail_v2beta_generated_user_event_service_purge_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_PurgeUserEvents_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 46, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 47, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_purge_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient.rejoin_user_events", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.RejoinUserEvents", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "RejoinUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RejoinUserEventsRequest" + }, + { + "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": "rejoin_user_events" + }, + "description": "Sample for RejoinUserEvents", + "file": "retail_v2beta_generated_user_event_service_rejoin_user_events_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_RejoinUserEvents_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": "retail_v2beta_generated_user_event_service_rejoin_user_events_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient.rejoin_user_events", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.RejoinUserEvents", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "RejoinUserEvents" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.RejoinUserEventsRequest" + }, + { + "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": "rejoin_user_events" + }, + "description": "Sample for RejoinUserEvents", + "file": "retail_v2beta_generated_user_event_service_rejoin_user_events_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_RejoinUserEvents_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": "retail_v2beta_generated_user_event_service_rejoin_user_events_sync.py" + }, + { + "canonical": true, + "clientMethod": { + "async": true, + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient", + "shortName": "UserEventServiceAsyncClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceAsyncClient.write_user_event", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.WriteUserEvent", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "WriteUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.WriteUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.UserEvent", + "shortName": "write_user_event" + }, + "description": "Sample for WriteUserEvent", + "file": "retail_v2beta_generated_user_event_service_write_user_event_async.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_WriteUserEvent_async", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_write_user_event_async.py" + }, + { + "canonical": true, + "clientMethod": { + "client": { + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient", + "shortName": "UserEventServiceClient" + }, + "fullName": "google.cloud.retail_v2beta.UserEventServiceClient.write_user_event", + "method": { + "fullName": "google.cloud.retail.v2beta.UserEventService.WriteUserEvent", + "service": { + "fullName": "google.cloud.retail.v2beta.UserEventService", + "shortName": "UserEventService" + }, + "shortName": "WriteUserEvent" + }, + "parameters": [ + { + "name": "request", + "type": "google.cloud.retail_v2beta.types.WriteUserEventRequest" + }, + { + "name": "retry", + "type": "google.api_core.retry.Retry" + }, + { + "name": "timeout", + "type": "float" + }, + { + "name": "metadata", + "type": "Sequence[Tuple[str, str]" + } + ], + "resultType": "google.cloud.retail_v2beta.types.UserEvent", + "shortName": "write_user_event" + }, + "description": "Sample for WriteUserEvent", + "file": "retail_v2beta_generated_user_event_service_write_user_event_sync.py", + "language": "PYTHON", + "origin": "API_DEFINITION", + "regionTag": "retail_v2beta_generated_UserEventService_WriteUserEvent_sync", + "segments": [ + { + "end": 56, + "start": 27, + "type": "FULL" + }, + { + "end": 56, + "start": 27, + "type": "SHORT" + }, + { + "end": 40, + "start": 38, + "type": "CLIENT_INITIALIZATION" + }, + { + "end": 50, + "start": 41, + "type": "REQUEST_INITIALIZATION" + }, + { + "end": 53, + "start": 51, + "type": "REQUEST_EXECUTION" + }, + { + "end": 57, + "start": 54, + "type": "RESPONSE_HANDLING" + } + ], + "title": "retail_v2beta_generated_user_event_service_write_user_event_sync.py" + } + ] +} diff --git a/owl-bot-staging/v2beta/scripts/fixup_retail_v2beta_keywords.py b/owl-bot-staging/v2beta/scripts/fixup_retail_v2beta_keywords.py new file mode 100644 index 00000000..4610d750 --- /dev/null +++ b/owl-bot-staging/v2beta/scripts/fixup_retail_v2beta_keywords.py @@ -0,0 +1,227 @@ +#! /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 retailCallTransformer(cst.CSTTransformer): + CTRL_PARAMS: Tuple[str] = ('retry', 'timeout', 'metadata') + METHOD_TO_PARAMS: Dict[str, Tuple[str]] = { + 'add_catalog_attribute': ('attributes_config', 'catalog_attribute', ), + 'add_control': ('serving_config', 'control_id', ), + 'add_fulfillment_places': ('product', 'type_', 'place_ids', 'add_time', 'allow_missing', ), + 'add_local_inventories': ('product', 'local_inventories', 'add_mask', 'add_time', 'allow_missing', ), + 'batch_remove_catalog_attributes': ('attributes_config', 'attribute_keys', ), + 'collect_user_event': ('parent', 'user_event', 'prebuilt_rule', 'uri', 'ets', 'raw_json', ), + 'complete_query': ('catalog', 'query', 'visitor_id', 'language_codes', 'device_type', 'dataset', 'max_suggestions', 'entity', ), + 'create_control': ('parent', 'control', 'control_id', ), + 'create_model': ('parent', 'model', 'dry_run', ), + 'create_product': ('parent', 'product', 'product_id', ), + 'create_serving_config': ('parent', 'serving_config', 'serving_config_id', ), + 'delete_control': ('name', ), + 'delete_model': ('name', ), + 'delete_product': ('name', ), + 'delete_serving_config': ('name', ), + 'get_attributes_config': ('name', ), + 'get_completion_config': ('name', ), + 'get_control': ('name', ), + 'get_default_branch': ('catalog', ), + 'get_model': ('name', ), + 'get_product': ('name', ), + 'get_serving_config': ('name', ), + 'import_completion_data': ('parent', 'input_config', 'notification_pubsub_topic', ), + 'import_products': ('parent', 'input_config', 'request_id', 'errors_config', 'update_mask', 'reconciliation_mode', 'notification_pubsub_topic', ), + 'import_user_events': ('parent', 'input_config', 'errors_config', ), + 'list_catalogs': ('parent', 'page_size', 'page_token', ), + 'list_controls': ('parent', 'page_size', 'page_token', 'filter', ), + 'list_models': ('parent', 'page_size', 'page_token', ), + 'list_products': ('parent', 'page_size', 'page_token', 'filter', 'read_mask', ), + 'list_serving_configs': ('parent', 'page_size', 'page_token', ), + 'pause_model': ('name', ), + 'predict': ('placement', 'user_event', 'page_size', 'page_token', 'filter', 'validate_only', 'params', 'labels', ), + 'purge_user_events': ('parent', 'filter', 'force', ), + 'rejoin_user_events': ('parent', 'user_event_rejoin_scope', ), + 'remove_catalog_attribute': ('attributes_config', 'key', ), + 'remove_control': ('serving_config', 'control_id', ), + 'remove_fulfillment_places': ('product', 'type_', 'place_ids', 'remove_time', 'allow_missing', ), + 'remove_local_inventories': ('product', 'place_ids', 'remove_time', 'allow_missing', ), + 'replace_catalog_attribute': ('attributes_config', 'catalog_attribute', 'update_mask', ), + 'resume_model': ('name', ), + 'search': ('placement', 'visitor_id', 'branch', 'query', 'user_info', 'page_size', 'page_token', 'offset', 'filter', 'canonical_filter', 'order_by', 'facet_specs', 'dynamic_facet_spec', 'boost_spec', 'query_expansion_spec', 'variant_rollup_keys', 'page_categories', 'search_mode', 'personalization_spec', 'labels', 'spell_correction_spec', 'entity', ), + 'set_default_branch': ('catalog', 'branch_id', 'note', 'force', ), + 'set_inventory': ('inventory', 'set_mask', 'set_time', 'allow_missing', ), + 'tune_model': ('name', ), + 'update_attributes_config': ('attributes_config', 'update_mask', ), + 'update_catalog': ('catalog', 'update_mask', ), + 'update_completion_config': ('completion_config', 'update_mask', ), + 'update_control': ('control', 'update_mask', ), + 'update_model': ('model', 'update_mask', ), + 'update_product': ('product', 'update_mask', 'allow_missing', ), + 'update_serving_config': ('serving_config', 'update_mask', ), + 'write_user_event': ('parent', 'user_event', 'write_async', ), + } + + 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=retailCallTransformer(), +): + """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 retail 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/v2beta/setup.py b/owl-bot-staging/v2beta/setup.py new file mode 100644 index 00000000..458c0728 --- /dev/null +++ b/owl-bot-staging/v2beta/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-retail' + + +description = "Google Cloud Retail API client library" + +version = {} +with open(os.path.join(package_root, 'google/cloud/retail/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-retail" + +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/v2beta/testing/constraints-3.10.txt b/owl-bot-staging/v2beta/testing/constraints-3.10.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/testing/constraints-3.11.txt b/owl-bot-staging/v2beta/testing/constraints-3.11.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/testing/constraints-3.12.txt b/owl-bot-staging/v2beta/testing/constraints-3.12.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/testing/constraints-3.7.txt b/owl-bot-staging/v2beta/testing/constraints-3.7.txt new file mode 100644 index 00000000..6c44adfe --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/testing/constraints-3.8.txt b/owl-bot-staging/v2beta/testing/constraints-3.8.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/testing/constraints-3.9.txt b/owl-bot-staging/v2beta/testing/constraints-3.9.txt new file mode 100644 index 00000000..ed7f9aed --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/tests/__init__.py b/owl-bot-staging/v2beta/tests/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/tests/unit/__init__.py b/owl-bot-staging/v2beta/tests/unit/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/tests/unit/gapic/__init__.py b/owl-bot-staging/v2beta/tests/unit/gapic/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2beta/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/v2beta/tests/unit/gapic/retail_v2beta/__init__.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/__init__.py new file mode 100644 index 00000000..1b4db446 --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/__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/v2beta/tests/unit/gapic/retail_v2beta/test_catalog_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_catalog_service.py new file mode 100644 index 00000000..ad7efc35 --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_catalog_service.py @@ -0,0 +1,6992 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.catalog_service import CatalogServiceAsyncClient +from google.cloud.retail_v2beta.services.catalog_service import CatalogServiceClient +from google.cloud.retail_v2beta.services.catalog_service import pagers +from google.cloud.retail_v2beta.services.catalog_service import transports +from google.cloud.retail_v2beta.types import catalog +from google.cloud.retail_v2beta.types import catalog as gcr_catalog +from google.cloud.retail_v2beta.types import catalog_service +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.type import date_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 CatalogServiceClient._get_default_mtls_endpoint(None) is None + assert CatalogServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CatalogServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (CatalogServiceClient, "grpc"), + (CatalogServiceAsyncClient, "grpc_asyncio"), + (CatalogServiceClient, "rest"), +]) +def test_catalog_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CatalogServiceGrpcTransport, "grpc"), + (transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.CatalogServiceRestTransport, "rest"), +]) +def test_catalog_service_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", [ + (CatalogServiceClient, "grpc"), + (CatalogServiceAsyncClient, "grpc_asyncio"), + (CatalogServiceClient, "rest"), +]) +def test_catalog_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_catalog_service_client_get_transport_class(): + transport = CatalogServiceClient.get_transport_class() + available_transports = [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceRestTransport, + ] + assert transport in available_transports + + transport = CatalogServiceClient.get_transport_class("grpc") + assert transport == transports.CatalogServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_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(CatalogServiceClient, '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(CatalogServiceClient, '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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "true"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", "false"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", "true"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_catalog_service_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", [ + CatalogServiceClient, CatalogServiceAsyncClient +]) +@mock.patch.object(CatalogServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceClient)) +@mock.patch.object(CatalogServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CatalogServiceAsyncClient)) +def test_catalog_service_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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc"), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest"), +]) +def test_catalog_service_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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", grpc_helpers), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (CatalogServiceClient, transports.CatalogServiceRestTransport, "rest", None), +]) +def test_catalog_service_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_catalog_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.catalog_service.transports.CatalogServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CatalogServiceClient( + 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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport, "grpc", grpc_helpers), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_catalog_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ListCatalogsRequest, + dict, +]) +def test_list_catalogs(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_catalogs_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 = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + client.list_catalogs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + +@pytest.mark.asyncio +async def test_list_catalogs_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ListCatalogsRequest): + client = CatalogServiceAsyncClient( + 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_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_catalogs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ListCatalogsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_catalogs_async_from_dict(): + await test_list_catalogs_async(request_type=dict) + + +def test_list_catalogs_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = catalog_service.ListCatalogsResponse() + client.list_catalogs(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_catalogs_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.ListCatalogsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + await client.list_catalogs(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_catalogs_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_catalogs( + 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_catalogs_flattened_error(): + client = CatalogServiceClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_catalogs_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.ListCatalogsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.ListCatalogsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_catalogs( + 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_catalogs_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + + +def test_list_catalogs_pager(transport_name: str = "grpc"): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_catalogs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in results) +def test_list_catalogs_pages(transport_name: str = "grpc"): + client = CatalogServiceClient( + 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_catalogs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + pages = list(client.list_catalogs(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_catalogs_async_pager(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_catalogs(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, catalog.Catalog) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_catalogs_async_pages(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_catalogs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + 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_catalogs(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", [ + catalog_service.UpdateCatalogRequest, + dict, +]) +def test_update_catalog(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + ) + response = client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_catalog_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 = CatalogServiceClient( + 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_catalog), + '__call__') as call: + client.update_catalog() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + +@pytest.mark.asyncio +async def test_update_catalog_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCatalogRequest): + client = CatalogServiceAsyncClient( + 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_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + )) + response = await client.update_catalog(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCatalogRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +@pytest.mark.asyncio +async def test_update_catalog_async_from_dict(): + await test_update_catalog_async(request_type=dict) + + +def test_update_catalog_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = gcr_catalog.Catalog() + client.update_catalog(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', + 'catalog.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_catalog_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateCatalogRequest() + + request.catalog.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + await client.update_catalog(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', + 'catalog.name=name_value', + ) in kw['metadata'] + + +def test_update_catalog_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_catalog( + catalog=gcr_catalog.Catalog(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].catalog + mock_val = gcr_catalog.Catalog(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_catalog_flattened_error(): + client = CatalogServiceClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_catalog_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_catalog), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_catalog.Catalog() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_catalog.Catalog()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_catalog( + catalog=gcr_catalog.Catalog(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].catalog + mock_val = gcr_catalog.Catalog(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_catalog_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.SetDefaultBranchRequest, + dict, +]) +def test_set_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_set_default_branch_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 = CatalogServiceClient( + 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.set_default_branch), + '__call__') as call: + client.set_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + +@pytest.mark.asyncio +async def test_set_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.SetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + 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.set_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.set_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.SetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_set_default_branch_async_from_dict(): + await test_set_default_branch_async(request_type=dict) + + +def test_set_default_branch_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = None + client.set_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.SetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.set_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +def test_set_default_branch_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__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.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_set_default_branch_flattened_error(): + client = CatalogServiceClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_default_branch), + '__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.set_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_set_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetDefaultBranchRequest, + dict, +]) +def test_get_default_branch(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + ) + response = client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +def test_get_default_branch_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 = CatalogServiceClient( + 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_default_branch), + '__call__') as call: + client.get_default_branch() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + +@pytest.mark.asyncio +async def test_get_default_branch_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetDefaultBranchRequest): + client = CatalogServiceAsyncClient( + 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_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + )) + response = await client.get_default_branch(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetDefaultBranchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +@pytest.mark.asyncio +async def test_get_default_branch_async_from_dict(): + await test_get_default_branch_async(request_type=dict) + + +def test_get_default_branch_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = catalog_service.GetDefaultBranchResponse() + client.get_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_get_default_branch_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetDefaultBranchRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + await client.get_default_branch(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +def test_get_default_branch_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + + +def test_get_default_branch_flattened_error(): + client = CatalogServiceClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_default_branch), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.GetDefaultBranchResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.GetDefaultBranchResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_default_branch( + catalog='catalog_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].catalog + mock_val = 'catalog_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_get_default_branch_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetCompletionConfigRequest, + dict, +]) +def test_get_completion_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + response = client.get_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_get_completion_config_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 = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + client.get_completion_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + +@pytest.mark.asyncio +async def test_get_completion_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetCompletionConfigRequest): + client = CatalogServiceAsyncClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + )) + response = await client.get_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +@pytest.mark.asyncio +async def test_get_completion_config_async_from_dict(): + await test_get_completion_config_async(request_type=dict) + + +def test_get_completion_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetCompletionConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + call.return_value = catalog.CompletionConfig() + client.get_completion_config(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_completion_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetCompletionConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + await client.get_completion_config(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_completion_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_completion_config( + 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_completion_config_flattened_error(): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_completion_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_completion_config( + 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_completion_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateCompletionConfigRequest, + dict, +]) +def test_update_completion_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + response = client.update_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_update_completion_config_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 = CatalogServiceClient( + 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_completion_config), + '__call__') as call: + client.update_completion_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + +@pytest.mark.asyncio +async def test_update_completion_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateCompletionConfigRequest): + client = CatalogServiceAsyncClient( + 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_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + )) + response = await client.update_completion_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateCompletionConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +@pytest.mark.asyncio +async def test_update_completion_config_async_from_dict(): + await test_update_completion_config_async(request_type=dict) + + +def test_update_completion_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateCompletionConfigRequest() + + request.completion_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + call.return_value = catalog.CompletionConfig() + client.update_completion_config(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', + 'completion_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_completion_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateCompletionConfigRequest() + + request.completion_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + await client.update_completion_config(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', + 'completion_config.name=name_value', + ) in kw['metadata'] + + +def test_update_completion_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_completion_config( + completion_config=catalog.CompletionConfig(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].completion_config + mock_val = catalog.CompletionConfig(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_completion_config_flattened_error(): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_completion_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_completion_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.CompletionConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.CompletionConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_completion_config( + completion_config=catalog.CompletionConfig(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].completion_config + mock_val = catalog.CompletionConfig(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_completion_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetAttributesConfigRequest, + dict, +]) +def test_get_attributes_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.get_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_get_attributes_config_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 = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + client.get_attributes_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + +@pytest.mark.asyncio +async def test_get_attributes_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.GetAttributesConfigRequest): + client = CatalogServiceAsyncClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.get_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.GetAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_get_attributes_config_async_from_dict(): + await test_get_attributes_config_async(request_type=dict) + + +def test_get_attributes_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.GetAttributesConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.get_attributes_config(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_attributes_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.GetAttributesConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.get_attributes_config(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_attributes_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_attributes_config( + 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_attributes_config_flattened_error(): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_attributes_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_attributes_config( + 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_attributes_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateAttributesConfigRequest, + dict, +]) +def test_update_attributes_config(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.update_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_update_attributes_config_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 = CatalogServiceClient( + 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_attributes_config), + '__call__') as call: + client.update_attributes_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + +@pytest.mark.asyncio +async def test_update_attributes_config_async(transport: str = 'grpc_asyncio', request_type=catalog_service.UpdateAttributesConfigRequest): + client = CatalogServiceAsyncClient( + 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_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.update_attributes_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.UpdateAttributesConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_update_attributes_config_async_from_dict(): + await test_update_attributes_config_async(request_type=dict) + + +def test_update_attributes_config_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.UpdateAttributesConfigRequest() + + request.attributes_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.update_attributes_config(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', + 'attributes_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_attributes_config_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.UpdateAttributesConfigRequest() + + request.attributes_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.update_attributes_config(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', + 'attributes_config.name=name_value', + ) in kw['metadata'] + + +def test_update_attributes_config_flattened(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_attributes_config( + attributes_config=catalog.AttributesConfig(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].attributes_config + mock_val = catalog.AttributesConfig(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_attributes_config_flattened_error(): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_attributes_config_flattened_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_attributes_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_attributes_config( + attributes_config=catalog.AttributesConfig(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].attributes_config + mock_val = catalog.AttributesConfig(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_attributes_config_flattened_error_async(): + client = CatalogServiceAsyncClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.AddCatalogAttributeRequest, + dict, +]) +def test_add_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.add_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_add_catalog_attribute_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 = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + client.add_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_add_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.AddCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.add_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.AddCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_add_catalog_attribute_async_from_dict(): + await test_add_catalog_attribute_async(request_type=dict) + + +def test_add_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.AddCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.add_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.AddCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.add_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.RemoveCatalogAttributeRequest, + dict, +]) +def test_remove_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.remove_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_remove_catalog_attribute_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 = CatalogServiceClient( + 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_catalog_attribute), + '__call__') as call: + client.remove_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.RemoveCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.remove_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.RemoveCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_async_from_dict(): + await test_remove_catalog_attribute_async(request_type=dict) + + +def test_remove_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.RemoveCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.remove_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.RemoveCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.remove_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.BatchRemoveCatalogAttributesRequest, + dict, +]) +def test_batch_remove_catalog_attributes(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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_remove_catalog_attributes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=['deleted_catalog_attributes_value'], + reset_catalog_attributes=['reset_catalog_attributes_value'], + ) + response = client.batch_remove_catalog_attributes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ['deleted_catalog_attributes_value'] + assert response.reset_catalog_attributes == ['reset_catalog_attributes_value'] + + +def test_batch_remove_catalog_attributes_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 = CatalogServiceClient( + 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_remove_catalog_attributes), + '__call__') as call: + client.batch_remove_catalog_attributes() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_async(transport: str = 'grpc_asyncio', request_type=catalog_service.BatchRemoveCatalogAttributesRequest): + client = CatalogServiceAsyncClient( + 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_remove_catalog_attributes), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=['deleted_catalog_attributes_value'], + reset_catalog_attributes=['reset_catalog_attributes_value'], + )) + response = await client.batch_remove_catalog_attributes(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.BatchRemoveCatalogAttributesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ['deleted_catalog_attributes_value'] + assert response.reset_catalog_attributes == ['reset_catalog_attributes_value'] + + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_async_from_dict(): + await test_batch_remove_catalog_attributes_async(request_type=dict) + + +def test_batch_remove_catalog_attributes_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.BatchRemoveCatalogAttributesRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_remove_catalog_attributes), + '__call__') as call: + call.return_value = catalog_service.BatchRemoveCatalogAttributesResponse() + client.batch_remove_catalog_attributes(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_batch_remove_catalog_attributes_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.BatchRemoveCatalogAttributesRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.batch_remove_catalog_attributes), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog_service.BatchRemoveCatalogAttributesResponse()) + await client.batch_remove_catalog_attributes(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ReplaceCatalogAttributeRequest, + dict, +]) +def test_replace_catalog_attribute(request_type, transport: str = 'grpc'): + client = CatalogServiceClient( + 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.replace_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + response = client.replace_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_replace_catalog_attribute_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 = CatalogServiceClient( + 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.replace_catalog_attribute), + '__call__') as call: + client.replace_catalog_attribute() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_async(transport: str = 'grpc_asyncio', request_type=catalog_service.ReplaceCatalogAttributeRequest): + client = CatalogServiceAsyncClient( + 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.replace_catalog_attribute), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + )) + response = await client.replace_catalog_attribute(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == catalog_service.ReplaceCatalogAttributeRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_async_from_dict(): + await test_replace_catalog_attribute_async(request_type=dict) + + +def test_replace_catalog_attribute_field_headers(): + client = CatalogServiceClient( + 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 = catalog_service.ReplaceCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.replace_catalog_attribute), + '__call__') as call: + call.return_value = catalog.AttributesConfig() + client.replace_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_replace_catalog_attribute_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = catalog_service.ReplaceCatalogAttributeRequest() + + request.attributes_config = 'attributes_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.replace_catalog_attribute), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(catalog.AttributesConfig()) + await client.replace_catalog_attribute(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', + 'attributes_config=attributes_config_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ListCatalogsRequest, + dict, +]) +def test_list_catalogs_rest(request_type): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_catalogs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListCatalogsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_catalogs_rest_required_fields(request_type=catalog_service.ListCatalogsRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_catalogs._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_catalogs._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog_service.ListCatalogsResponse() + # 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 + + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_catalogs(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_catalogs_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_catalogs._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_catalogs_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_list_catalogs") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_list_catalogs") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.ListCatalogsRequest.pb(catalog_service.ListCatalogsRequest()) + 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 = catalog_service.ListCatalogsResponse.to_json(catalog_service.ListCatalogsResponse()) + + request = catalog_service.ListCatalogsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.ListCatalogsResponse() + + client.list_catalogs(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_catalogs_rest_bad_request(transport: str = 'rest', request_type=catalog_service.ListCatalogsRequest): + client = CatalogServiceClient( + 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_catalogs(request) + + +def test_list_catalogs_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog_service.ListCatalogsResponse() + + # 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 + pb_return_value = catalog_service.ListCatalogsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_catalogs(**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/v2beta/{parent=projects/*/locations/*}/catalogs" % client.transport._host, args[1]) + + +def test_list_catalogs_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_catalogs( + catalog_service.ListCatalogsRequest(), + parent='parent_value', + ) + + +def test_list_catalogs_rest_pager(transport: str = 'rest'): + client = CatalogServiceClient( + 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 = ( + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + catalog.Catalog(), + ], + next_page_token='abc', + ), + catalog_service.ListCatalogsResponse( + catalogs=[], + next_page_token='def', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + ], + next_page_token='ghi', + ), + catalog_service.ListCatalogsResponse( + catalogs=[ + catalog.Catalog(), + catalog.Catalog(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(catalog_service.ListCatalogsResponse.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_catalogs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, catalog.Catalog) + for i in results) + + pages = list(client.list_catalogs(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", [ + catalog_service.UpdateCatalogRequest, + dict, +]) +def test_update_catalog_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + request_init["catalog"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3', 'display_name': 'display_name_value', 'product_level_config': {'ingestion_product_type': 'ingestion_product_type_value', 'merchant_center_product_id_field': 'merchant_center_product_id_field_value'}, 'merchant_center_linking_config': {'links': [{'merchant_center_account_id': 2730, 'branch_id': 'branch_id_value', 'destinations': ['destinations_value1', 'destinations_value2'], 'region_code': 'region_code_value', 'language_code': 'language_code_value', 'feeds': [{'primary_feed_id': 1571, 'primary_feed_name': 'primary_feed_name_value'}]}]}} + 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 = gcr_catalog.Catalog( + name='name_value', + display_name='display_name_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_catalog(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_catalog.Catalog) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + + +def test_update_catalog_rest_required_fields(request_type=catalog_service.UpdateCatalogRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_catalog._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_catalog._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_catalog.Catalog() + # 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 + + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_catalog(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_catalog_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_catalog._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("catalog", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_catalog_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_catalog") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_catalog") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateCatalogRequest.pb(catalog_service.UpdateCatalogRequest()) + 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 = gcr_catalog.Catalog.to_json(gcr_catalog.Catalog()) + + request = catalog_service.UpdateCatalogRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_catalog.Catalog() + + client.update_catalog(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_catalog_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateCatalogRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + request_init["catalog"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3', 'display_name': 'display_name_value', 'product_level_config': {'ingestion_product_type': 'ingestion_product_type_value', 'merchant_center_product_id_field': 'merchant_center_product_id_field_value'}, 'merchant_center_linking_config': {'links': [{'merchant_center_account_id': 2730, 'branch_id': 'branch_id_value', 'destinations': ['destinations_value1', 'destinations_value2'], 'region_code': 'region_code_value', 'language_code': 'language_code_value', 'feeds': [{'primary_feed_id': 1571, 'primary_feed_name': 'primary_feed_name_value'}]}]}} + 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_catalog(request) + + +def test_update_catalog_rest_flattened(): + client = CatalogServiceClient( + 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 = gcr_catalog.Catalog() + + # get arguments that satisfy an http rule for this method + sample_request = {'catalog': {'name': 'projects/sample1/locations/sample2/catalogs/sample3'}} + + # get truthy value for each flattened field + mock_args = dict( + catalog=gcr_catalog.Catalog(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 + pb_return_value = gcr_catalog.Catalog.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_catalog(**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/v2beta/{catalog.name=projects/*/locations/*/catalogs/*}" % client.transport._host, args[1]) + + +def test_update_catalog_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_catalog( + catalog_service.UpdateCatalogRequest(), + catalog=gcr_catalog.Catalog(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_catalog_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.SetDefaultBranchRequest, + dict, +]) +def test_set_default_branch_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.set_default_branch(request) + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_default_branch_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "pre_set_default_branch") as pre: + pre.assert_not_called() + pb_message = catalog_service.SetDefaultBranchRequest.pb(catalog_service.SetDefaultBranchRequest()) + 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 = catalog_service.SetDefaultBranchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.set_default_branch(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_set_default_branch_rest_bad_request(transport: str = 'rest', request_type=catalog_service.SetDefaultBranchRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.set_default_branch(request) + + +def test_set_default_branch_rest_flattened(): + client = CatalogServiceClient( + 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 = {'catalog': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + catalog='catalog_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.set_default_branch(**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/v2beta/{catalog=projects/*/locations/*/catalogs/*}:setDefaultBranch" % client.transport._host, args[1]) + + +def test_set_default_branch_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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.set_default_branch( + catalog_service.SetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +def test_set_default_branch_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetDefaultBranchRequest, + dict, +]) +def test_get_default_branch_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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 = catalog_service.GetDefaultBranchResponse( + branch='branch_value', + note='note_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.GetDefaultBranchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_default_branch(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.GetDefaultBranchResponse) + assert response.branch == 'branch_value' + assert response.note == 'note_value' + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_default_branch_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_default_branch") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_default_branch") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetDefaultBranchRequest.pb(catalog_service.GetDefaultBranchRequest()) + 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 = catalog_service.GetDefaultBranchResponse.to_json(catalog_service.GetDefaultBranchResponse()) + + request = catalog_service.GetDefaultBranchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.GetDefaultBranchResponse() + + client.get_default_branch(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_default_branch_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetDefaultBranchRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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_default_branch(request) + + +def test_get_default_branch_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog_service.GetDefaultBranchResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'catalog': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + catalog='catalog_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.GetDefaultBranchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_default_branch(**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/v2beta/{catalog=projects/*/locations/*/catalogs/*}:getDefaultBranch" % client.transport._host, args[1]) + + +def test_get_default_branch_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_default_branch( + catalog_service.GetDefaultBranchRequest(), + catalog='catalog_value', + ) + + +def test_get_default_branch_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetCompletionConfigRequest, + dict, +]) +def test_get_completion_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + 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 = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_completion_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_get_completion_config_rest_required_fields(request_type=catalog_service.GetCompletionConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_completion_config._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_completion_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.CompletionConfig() + # 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 + + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_completion_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_completion_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_completion_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_completion_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_completion_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_completion_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetCompletionConfigRequest.pb(catalog_service.GetCompletionConfigRequest()) + 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 = catalog.CompletionConfig.to_json(catalog.CompletionConfig()) + + request = catalog_service.GetCompletionConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.CompletionConfig() + + client.get_completion_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_completion_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetCompletionConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + 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_completion_config(request) + + +def test_get_completion_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.CompletionConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'} + + # 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 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_completion_config(**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/v2beta/{name=projects/*/locations/*/catalogs/*/completionConfig}" % client.transport._host, args[1]) + + +def test_get_completion_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.GetCompletionConfigRequest(), + name='name_value', + ) + + +def test_get_completion_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateCompletionConfigRequest, + dict, +]) +def test_update_completion_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + request_init["completion_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig', 'matching_order': 'matching_order_value', 'max_suggestions': 1632, 'min_prefix_length': 1810, 'auto_learning': True, 'suggestions_input_config': {'big_query_source': {'partition_date': {'year': 433, 'month': 550, 'day': 318}, 'project_id': 'project_id_value', 'dataset_id': 'dataset_id_value', 'table_id': 'table_id_value', 'gcs_staging_dir': 'gcs_staging_dir_value', 'data_schema': 'data_schema_value'}}, 'last_suggestions_import_operation': 'last_suggestions_import_operation_value', 'denylist_input_config': {}, 'last_denylist_import_operation': 'last_denylist_import_operation_value', 'allowlist_input_config': {}, 'last_allowlist_import_operation': 'last_allowlist_import_operation_value'} + 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 = catalog.CompletionConfig( + name='name_value', + matching_order='matching_order_value', + max_suggestions=1632, + min_prefix_length=1810, + auto_learning=True, + last_suggestions_import_operation='last_suggestions_import_operation_value', + last_denylist_import_operation='last_denylist_import_operation_value', + last_allowlist_import_operation='last_allowlist_import_operation_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_completion_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.CompletionConfig) + assert response.name == 'name_value' + assert response.matching_order == 'matching_order_value' + assert response.max_suggestions == 1632 + assert response.min_prefix_length == 1810 + assert response.auto_learning is True + assert response.last_suggestions_import_operation == 'last_suggestions_import_operation_value' + assert response.last_denylist_import_operation == 'last_denylist_import_operation_value' + assert response.last_allowlist_import_operation == 'last_allowlist_import_operation_value' + + +def test_update_completion_config_rest_required_fields(request_type=catalog_service.UpdateCompletionConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_completion_config._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_completion_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.CompletionConfig() + # 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 + + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_completion_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_completion_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_completion_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("completionConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_completion_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_completion_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_completion_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateCompletionConfigRequest.pb(catalog_service.UpdateCompletionConfigRequest()) + 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 = catalog.CompletionConfig.to_json(catalog.CompletionConfig()) + + request = catalog_service.UpdateCompletionConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.CompletionConfig() + + client.update_completion_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_completion_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateCompletionConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + request_init["completion_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig', 'matching_order': 'matching_order_value', 'max_suggestions': 1632, 'min_prefix_length': 1810, 'auto_learning': True, 'suggestions_input_config': {'big_query_source': {'partition_date': {'year': 433, 'month': 550, 'day': 318}, 'project_id': 'project_id_value', 'dataset_id': 'dataset_id_value', 'table_id': 'table_id_value', 'gcs_staging_dir': 'gcs_staging_dir_value', 'data_schema': 'data_schema_value'}}, 'last_suggestions_import_operation': 'last_suggestions_import_operation_value', 'denylist_input_config': {}, 'last_denylist_import_operation': 'last_denylist_import_operation_value', 'allowlist_input_config': {}, 'last_allowlist_import_operation': 'last_allowlist_import_operation_value'} + 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_completion_config(request) + + +def test_update_completion_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.CompletionConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'completion_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/completionConfig'}} + + # get truthy value for each flattened field + mock_args = dict( + completion_config=catalog.CompletionConfig(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 + pb_return_value = catalog.CompletionConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_completion_config(**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/v2beta/{completion_config.name=projects/*/locations/*/catalogs/*/completionConfig}" % client.transport._host, args[1]) + + +def test_update_completion_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_completion_config( + catalog_service.UpdateCompletionConfigRequest(), + completion_config=catalog.CompletionConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_completion_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.GetAttributesConfigRequest, + dict, +]) +def test_get_attributes_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_attributes_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_get_attributes_config_rest_required_fields(request_type=catalog_service.GetAttributesConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_attributes_config._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_attributes_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_attributes_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_attributes_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_attributes_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_attributes_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_get_attributes_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_get_attributes_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.GetAttributesConfigRequest.pb(catalog_service.GetAttributesConfigRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.GetAttributesConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.get_attributes_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_attributes_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.GetAttributesConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_attributes_config(request) + + +def test_get_attributes_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.AttributesConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + + # 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 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_attributes_config(**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/v2beta/{name=projects/*/locations/*/catalogs/*/attributesConfig}" % client.transport._host, args[1]) + + +def test_get_attributes_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.GetAttributesConfigRequest(), + name='name_value', + ) + + +def test_get_attributes_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.UpdateAttributesConfigRequest, + dict, +]) +def test_update_attributes_config_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + request_init["attributes_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig', 'catalog_attributes': {}, 'attribute_config_level': 1} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_attributes_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_update_attributes_config_rest_required_fields(request_type=catalog_service.UpdateAttributesConfigRequest): + transport_class = transports.CatalogServiceRestTransport + + 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_attributes_config._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_attributes_config._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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_attributes_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_attributes_config_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_attributes_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("attributesConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_attributes_config_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_update_attributes_config") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_update_attributes_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.UpdateAttributesConfigRequest.pb(catalog_service.UpdateAttributesConfigRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.UpdateAttributesConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.update_attributes_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_attributes_config_rest_bad_request(transport: str = 'rest', request_type=catalog_service.UpdateAttributesConfigRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + request_init["attributes_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig', 'catalog_attributes': {}, 'attribute_config_level': 1} + 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_attributes_config(request) + + +def test_update_attributes_config_rest_flattened(): + client = CatalogServiceClient( + 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 = catalog.AttributesConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'attributes_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'}} + + # get truthy value for each flattened field + mock_args = dict( + attributes_config=catalog.AttributesConfig(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 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_attributes_config(**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/v2beta/{attributes_config.name=projects/*/locations/*/catalogs/*/attributesConfig}" % client.transport._host, args[1]) + + +def test_update_attributes_config_rest_flattened_error(transport: str = 'rest'): + client = CatalogServiceClient( + 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_attributes_config( + catalog_service.UpdateAttributesConfigRequest(), + attributes_config=catalog.AttributesConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_attributes_config_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.AddCatalogAttributeRequest, + dict, +]) +def test_add_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_add_catalog_attribute_rest_required_fields(request_type=catalog_service.AddCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + 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_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "catalogAttribute", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_add_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_add_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.AddCatalogAttributeRequest.pb(catalog_service.AddCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.AddCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.add_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.AddCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_catalog_attribute(request) + + +def test_add_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.RemoveCatalogAttributeRequest, + dict, +]) +def test_remove_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_remove_catalog_attribute_rest_required_fields(request_type=catalog_service.RemoveCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + request_init["key"] = "" + 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_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + jsonified_request["key"] = 'key_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + assert "key" in jsonified_request + assert jsonified_request["key"] == 'key_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "key", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_remove_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_remove_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.RemoveCatalogAttributeRequest.pb(catalog_service.RemoveCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.RemoveCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.remove_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.RemoveCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_catalog_attribute(request) + + +def test_remove_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.BatchRemoveCatalogAttributesRequest, + dict, +]) +def test_batch_remove_catalog_attributes_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog_service.BatchRemoveCatalogAttributesResponse( + deleted_catalog_attributes=['deleted_catalog_attributes_value'], + reset_catalog_attributes=['reset_catalog_attributes_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog_service.BatchRemoveCatalogAttributesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.batch_remove_catalog_attributes(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog_service.BatchRemoveCatalogAttributesResponse) + assert response.deleted_catalog_attributes == ['deleted_catalog_attributes_value'] + assert response.reset_catalog_attributes == ['reset_catalog_attributes_value'] + + +def test_batch_remove_catalog_attributes_rest_required_fields(request_type=catalog_service.BatchRemoveCatalogAttributesRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + request_init["attribute_keys"] = "" + 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_remove_catalog_attributes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + jsonified_request["attributeKeys"] = 'attribute_keys_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).batch_remove_catalog_attributes._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + assert "attributeKeys" in jsonified_request + assert jsonified_request["attributeKeys"] == 'attribute_keys_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog_service.BatchRemoveCatalogAttributesResponse() + # 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 + + pb_return_value = catalog_service.BatchRemoveCatalogAttributesResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.batch_remove_catalog_attributes(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_batch_remove_catalog_attributes_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.batch_remove_catalog_attributes._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "attributeKeys", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_batch_remove_catalog_attributes_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_batch_remove_catalog_attributes") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_batch_remove_catalog_attributes") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.BatchRemoveCatalogAttributesRequest.pb(catalog_service.BatchRemoveCatalogAttributesRequest()) + 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 = catalog_service.BatchRemoveCatalogAttributesResponse.to_json(catalog_service.BatchRemoveCatalogAttributesResponse()) + + request = catalog_service.BatchRemoveCatalogAttributesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog_service.BatchRemoveCatalogAttributesResponse() + + client.batch_remove_catalog_attributes(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_batch_remove_catalog_attributes_rest_bad_request(transport: str = 'rest', request_type=catalog_service.BatchRemoveCatalogAttributesRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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_remove_catalog_attributes(request) + + +def test_batch_remove_catalog_attributes_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + catalog_service.ReplaceCatalogAttributeRequest, + dict, +]) +def test_replace_catalog_attribute_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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 = catalog.AttributesConfig( + name='name_value', + attribute_config_level=common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.replace_catalog_attribute(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, catalog.AttributesConfig) + assert response.name == 'name_value' + assert response.attribute_config_level == common.AttributeConfigLevel.PRODUCT_LEVEL_ATTRIBUTE_CONFIG + + +def test_replace_catalog_attribute_rest_required_fields(request_type=catalog_service.ReplaceCatalogAttributeRequest): + transport_class = transports.CatalogServiceRestTransport + + request_init = {} + request_init["attributes_config"] = "" + 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()).replace_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["attributesConfig"] = 'attributes_config_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).replace_catalog_attribute._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "attributesConfig" in jsonified_request + assert jsonified_request["attributesConfig"] == 'attributes_config_value' + + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = catalog.AttributesConfig() + # 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 + + pb_return_value = catalog.AttributesConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.replace_catalog_attribute(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_replace_catalog_attribute_rest_unset_required_fields(): + transport = transports.CatalogServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.replace_catalog_attribute._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("attributesConfig", "catalogAttribute", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_replace_catalog_attribute_rest_interceptors(null_interceptor): + transport = transports.CatalogServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CatalogServiceRestInterceptor(), + ) + client = CatalogServiceClient(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.CatalogServiceRestInterceptor, "post_replace_catalog_attribute") as post, \ + mock.patch.object(transports.CatalogServiceRestInterceptor, "pre_replace_catalog_attribute") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = catalog_service.ReplaceCatalogAttributeRequest.pb(catalog_service.ReplaceCatalogAttributeRequest()) + 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 = catalog.AttributesConfig.to_json(catalog.AttributesConfig()) + + request = catalog_service.ReplaceCatalogAttributeRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = catalog.AttributesConfig() + + client.replace_catalog_attribute(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_replace_catalog_attribute_rest_bad_request(transport: str = 'rest', request_type=catalog_service.ReplaceCatalogAttributeRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'attributes_config': 'projects/sample1/locations/sample2/catalogs/sample3/attributesConfig'} + 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.replace_catalog_attribute(request) + + +def test_replace_catalog_attribute_rest_error(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CatalogServiceClient( + 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 = CatalogServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CatalogServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CatalogServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CatalogServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CatalogServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + transports.CatalogServiceRestTransport, +]) +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 = CatalogServiceClient.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 = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CatalogServiceGrpcTransport, + ) + +def test_catalog_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_catalog_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.catalog_service.transports.CatalogServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CatalogServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'list_catalogs', + 'update_catalog', + 'set_default_branch', + 'get_default_branch', + 'get_completion_config', + 'update_completion_config', + 'get_attributes_config', + 'update_attributes_config', + 'add_catalog_attribute', + 'remove_catalog_attribute', + 'batch_remove_catalog_attributes', + 'replace_catalog_attribute', + 'get_operation', + 'list_operations', + ) + 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_catalog_service_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.retail_v2beta.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_catalog_service_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.retail_v2beta.services.catalog_service.transports.CatalogServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CatalogServiceTransport() + adc.assert_called_once() + + +def test_catalog_service_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) + CatalogServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + ], +) +def test_catalog_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CatalogServiceGrpcTransport, + transports.CatalogServiceGrpcAsyncIOTransport, + transports.CatalogServiceRestTransport, + ], +) +def test_catalog_service_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.CatalogServiceGrpcTransport, grpc_helpers), + (transports.CatalogServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_catalog_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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_catalog_service_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.CatalogServiceRestTransport ( + 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_catalog_service_host_no_port(transport_name): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_catalog_service_host_with_port(transport_name): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_catalog_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CatalogServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CatalogServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.list_catalogs._session + session2 = client2.transport.list_catalogs._session + assert session1 != session2 + session1 = client1.transport.update_catalog._session + session2 = client2.transport.update_catalog._session + assert session1 != session2 + session1 = client1.transport.set_default_branch._session + session2 = client2.transport.set_default_branch._session + assert session1 != session2 + session1 = client1.transport.get_default_branch._session + session2 = client2.transport.get_default_branch._session + assert session1 != session2 + session1 = client1.transport.get_completion_config._session + session2 = client2.transport.get_completion_config._session + assert session1 != session2 + session1 = client1.transport.update_completion_config._session + session2 = client2.transport.update_completion_config._session + assert session1 != session2 + session1 = client1.transport.get_attributes_config._session + session2 = client2.transport.get_attributes_config._session + assert session1 != session2 + session1 = client1.transport.update_attributes_config._session + session2 = client2.transport.update_attributes_config._session + assert session1 != session2 + session1 = client1.transport.add_catalog_attribute._session + session2 = client2.transport.add_catalog_attribute._session + assert session1 != session2 + session1 = client1.transport.remove_catalog_attribute._session + session2 = client2.transport.remove_catalog_attribute._session + assert session1 != session2 + session1 = client1.transport.batch_remove_catalog_attributes._session + session2 = client2.transport.batch_remove_catalog_attributes._session + assert session1 != session2 + session1 = client1.transport.replace_catalog_attribute._session + session2 = client2.transport.replace_catalog_attribute._session + assert session1 != session2 +def test_catalog_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcTransport( + 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_catalog_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CatalogServiceGrpcAsyncIOTransport( + 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.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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.CatalogServiceGrpcTransport, transports.CatalogServiceGrpcAsyncIOTransport]) +def test_catalog_service_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_attributes_config_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/attributesConfig".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.attributes_config_path(project, location, catalog) + assert expected == actual + + +def test_parse_attributes_config_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = CatalogServiceClient.attributes_config_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_attributes_config_path(path) + assert expected == actual + +def test_branch_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + branch = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = CatalogServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "branch": "clam", + } + path = CatalogServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_branch_path(path) + assert expected == actual + +def test_catalog_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "catalog": "mussel", + } + path = CatalogServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_completion_config_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/completionConfig".format(project=project, location=location, catalog=catalog, ) + actual = CatalogServiceClient.completion_config_path(project, location, catalog) + assert expected == actual + + +def test_parse_completion_config_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + } + path = CatalogServiceClient.completion_config_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_completion_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CatalogServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = CatalogServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = CatalogServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = CatalogServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CatalogServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = CatalogServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = CatalogServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = CatalogServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CatalogServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = CatalogServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CatalogServiceClient.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.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CatalogServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CatalogServiceClient.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 = CatalogServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = CatalogServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = CatalogServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = CatalogServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = CatalogServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = CatalogServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = CatalogServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = CatalogServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CatalogServiceClient( + 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 = CatalogServiceClient( + 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", [ + (CatalogServiceClient, transports.CatalogServiceGrpcTransport), + (CatalogServiceAsyncClient, transports.CatalogServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_completion_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_completion_service.py new file mode 100644 index 00000000..afefcd9e --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_completion_service.py @@ -0,0 +1,2307 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.completion_service import CompletionServiceAsyncClient +from google.cloud.retail_v2beta.services.completion_service import CompletionServiceClient +from google.cloud.retail_v2beta.services.completion_service import transports +from google.cloud.retail_v2beta.types import completion_service +from google.cloud.retail_v2beta.types import import_config +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.type import date_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 CompletionServiceClient._get_default_mtls_endpoint(None) is None + assert CompletionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert CompletionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (CompletionServiceClient, "grpc"), + (CompletionServiceAsyncClient, "grpc_asyncio"), + (CompletionServiceClient, "rest"), +]) +def test_completion_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.CompletionServiceGrpcTransport, "grpc"), + (transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.CompletionServiceRestTransport, "rest"), +]) +def test_completion_service_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", [ + (CompletionServiceClient, "grpc"), + (CompletionServiceAsyncClient, "grpc_asyncio"), + (CompletionServiceClient, "rest"), +]) +def test_completion_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_completion_service_client_get_transport_class(): + transport = CompletionServiceClient.get_transport_class() + available_transports = [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceRestTransport, + ] + assert transport in available_transports + + transport = CompletionServiceClient.get_transport_class("grpc") + assert transport == transports.CompletionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_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(CompletionServiceClient, '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(CompletionServiceClient, '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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "true"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", "false"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", "true"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_completion_service_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", [ + CompletionServiceClient, CompletionServiceAsyncClient +]) +@mock.patch.object(CompletionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceClient)) +@mock.patch.object(CompletionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(CompletionServiceAsyncClient)) +def test_completion_service_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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc"), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest"), +]) +def test_completion_service_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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", grpc_helpers), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (CompletionServiceClient, transports.CompletionServiceRestTransport, "rest", None), +]) +def test_completion_service_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_completion_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.completion_service.transports.CompletionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = CompletionServiceClient( + 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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport, "grpc", grpc_helpers), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_completion_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + completion_service.CompleteQueryRequest, + dict, +]) +def test_complete_query(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + ) + response = client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +def test_complete_query_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 = CompletionServiceClient( + 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.complete_query), + '__call__') as call: + client.complete_query() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + +@pytest.mark.asyncio +async def test_complete_query_async(transport: str = 'grpc_asyncio', request_type=completion_service.CompleteQueryRequest): + client = CompletionServiceAsyncClient( + 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.complete_query), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + )) + response = await client.complete_query(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == completion_service.CompleteQueryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +@pytest.mark.asyncio +async def test_complete_query_async_from_dict(): + await test_complete_query_async(request_type=dict) + + +def test_complete_query_field_headers(): + client = CompletionServiceClient( + 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 = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = completion_service.CompleteQueryResponse() + client.complete_query(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_complete_query_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = completion_service.CompleteQueryRequest() + + request.catalog = 'catalog_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.complete_query), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(completion_service.CompleteQueryResponse()) + await client.complete_query(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', + 'catalog=catalog_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportCompletionDataRequest, + dict, +]) +def test_import_completion_data(request_type, transport: str = 'grpc'): + client = CompletionServiceClient( + 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_completion_data), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_completion_data_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 = CompletionServiceClient( + 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_completion_data), + '__call__') as call: + client.import_completion_data() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + +@pytest.mark.asyncio +async def test_import_completion_data_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportCompletionDataRequest): + client = CompletionServiceAsyncClient( + 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_completion_data), + '__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_completion_data(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportCompletionDataRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_completion_data_async_from_dict(): + await test_import_completion_data_async(request_type=dict) + + +def test_import_completion_data_field_headers(): + client = CompletionServiceClient( + 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 = import_config.ImportCompletionDataRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_completion_data(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_completion_data_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = import_config.ImportCompletionDataRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_completion_data), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_completion_data(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'] + + +@pytest.mark.parametrize("request_type", [ + completion_service.CompleteQueryRequest, + dict, +]) +def test_complete_query_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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 = completion_service.CompleteQueryResponse( + attribution_token='attribution_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = completion_service.CompleteQueryResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.complete_query(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, completion_service.CompleteQueryResponse) + assert response.attribution_token == 'attribution_token_value' + + +def test_complete_query_rest_required_fields(request_type=completion_service.CompleteQueryRequest): + transport_class = transports.CompletionServiceRestTransport + + request_init = {} + request_init["catalog"] = "" + request_init["query"] = "" + 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 + assert "query" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).complete_query._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "query" in jsonified_request + assert jsonified_request["query"] == request_init["query"] + + jsonified_request["catalog"] = 'catalog_value' + jsonified_request["query"] = 'query_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).complete_query._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dataset", "device_type", "entity", "language_codes", "max_suggestions", "query", "visitor_id", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "catalog" in jsonified_request + assert jsonified_request["catalog"] == 'catalog_value' + assert "query" in jsonified_request + assert jsonified_request["query"] == 'query_value' + + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = completion_service.CompleteQueryResponse() + # 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 + + pb_return_value = completion_service.CompleteQueryResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.complete_query(request) + + expected_params = [ + ( + "query", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_complete_query_rest_unset_required_fields(): + transport = transports.CompletionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.complete_query._get_unset_required_fields({}) + assert set(unset_fields) == (set(("dataset", "deviceType", "entity", "languageCodes", "maxSuggestions", "query", "visitorId", )) & set(("catalog", "query", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_complete_query_rest_interceptors(null_interceptor): + transport = transports.CompletionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CompletionServiceRestInterceptor(), + ) + client = CompletionServiceClient(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.CompletionServiceRestInterceptor, "post_complete_query") as post, \ + mock.patch.object(transports.CompletionServiceRestInterceptor, "pre_complete_query") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = completion_service.CompleteQueryRequest.pb(completion_service.CompleteQueryRequest()) + 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 = completion_service.CompleteQueryResponse.to_json(completion_service.CompleteQueryResponse()) + + request = completion_service.CompleteQueryRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = completion_service.CompleteQueryResponse() + + client.complete_query(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_complete_query_rest_bad_request(transport: str = 'rest', request_type=completion_service.CompleteQueryRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'catalog': 'projects/sample1/locations/sample2/catalogs/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.complete_query(request) + + +def test_complete_query_rest_error(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportCompletionDataRequest, + dict, +]) +def test_import_completion_data_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_completion_data(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_completion_data_rest_required_fields(request_type=import_config.ImportCompletionDataRequest): + transport_class = transports.CompletionServiceRestTransport + + 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_completion_data._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_completion_data._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 = CompletionServiceClient( + 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_completion_data(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_completion_data_rest_unset_required_fields(): + transport = transports.CompletionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_completion_data._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_completion_data_rest_interceptors(null_interceptor): + transport = transports.CompletionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.CompletionServiceRestInterceptor(), + ) + client = CompletionServiceClient(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.CompletionServiceRestInterceptor, "post_import_completion_data") as post, \ + mock.patch.object(transports.CompletionServiceRestInterceptor, "pre_import_completion_data") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportCompletionDataRequest.pb(import_config.ImportCompletionDataRequest()) + 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 = import_config.ImportCompletionDataRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_completion_data(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_completion_data_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportCompletionDataRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.import_completion_data(request) + + +def test_import_completion_data_rest_error(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = CompletionServiceClient( + 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 = CompletionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = CompletionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = CompletionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.CompletionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.CompletionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + transports.CompletionServiceRestTransport, +]) +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 = CompletionServiceClient.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 = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.CompletionServiceGrpcTransport, + ) + +def test_completion_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_completion_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.completion_service.transports.CompletionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.CompletionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'complete_query', + 'import_completion_data', + 'get_operation', + 'list_operations', + ) + 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_completion_service_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.retail_v2beta.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_completion_service_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.retail_v2beta.services.completion_service.transports.CompletionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.CompletionServiceTransport() + adc.assert_called_once() + + +def test_completion_service_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) + CompletionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + ], +) +def test_completion_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.CompletionServiceGrpcTransport, + transports.CompletionServiceGrpcAsyncIOTransport, + transports.CompletionServiceRestTransport, + ], +) +def test_completion_service_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.CompletionServiceGrpcTransport, grpc_helpers), + (transports.CompletionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_completion_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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_completion_service_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.CompletionServiceRestTransport ( + 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_completion_service_rest_lro_client(): + client = CompletionServiceClient( + 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_completion_service_host_no_port(transport_name): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_completion_service_host_with_port(transport_name): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_completion_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = CompletionServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = CompletionServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.complete_query._session + session2 = client2.transport.complete_query._session + assert session1 != session2 + session1 = client1.transport.import_completion_data._session + session2 = client2.transport.import_completion_data._session + assert session1 != session2 +def test_completion_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcTransport( + 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_completion_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.CompletionServiceGrpcAsyncIOTransport( + 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.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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.CompletionServiceGrpcTransport, transports.CompletionServiceGrpcAsyncIOTransport]) +def test_completion_service_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_completion_service_grpc_lro_client(): + client = CompletionServiceClient( + 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_completion_service_grpc_lro_async_client(): + client = CompletionServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = CompletionServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = CompletionServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = CompletionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = CompletionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = CompletionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = CompletionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = CompletionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = CompletionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = CompletionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = CompletionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = CompletionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = CompletionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = CompletionServiceClient.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.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.CompletionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = CompletionServiceClient.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 = CompletionServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = CompletionServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = CompletionServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = CompletionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = CompletionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = CompletionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = CompletionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = CompletionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = CompletionServiceClient( + 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 = CompletionServiceClient( + 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", [ + (CompletionServiceClient, transports.CompletionServiceGrpcTransport), + (CompletionServiceAsyncClient, transports.CompletionServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_control_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_control_service.py new file mode 100644 index 00000000..3688e296 --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_control_service.py @@ -0,0 +1,4301 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.control_service import ControlServiceAsyncClient +from google.cloud.retail_v2beta.services.control_service import ControlServiceClient +from google.cloud.retail_v2beta.services.control_service import pagers +from google.cloud.retail_v2beta.services.control_service import transports +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import control +from google.cloud.retail_v2beta.types import control as gcr_control +from google.cloud.retail_v2beta.types import control_service +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_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 ControlServiceClient._get_default_mtls_endpoint(None) is None + assert ControlServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ControlServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ControlServiceClient, "grpc"), + (ControlServiceAsyncClient, "grpc_asyncio"), + (ControlServiceClient, "rest"), +]) +def test_control_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ControlServiceGrpcTransport, "grpc"), + (transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ControlServiceRestTransport, "rest"), +]) +def test_control_service_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", [ + (ControlServiceClient, "grpc"), + (ControlServiceAsyncClient, "grpc_asyncio"), + (ControlServiceClient, "rest"), +]) +def test_control_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_control_service_client_get_transport_class(): + transport = ControlServiceClient.get_transport_class() + available_transports = [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceRestTransport, + ] + assert transport in available_transports + + transport = ControlServiceClient.get_transport_class("grpc") + assert transport == transports.ControlServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest"), +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +def test_control_service_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(ControlServiceClient, '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(ControlServiceClient, '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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", "true"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", "false"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", "true"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_control_service_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", [ + ControlServiceClient, ControlServiceAsyncClient +]) +@mock.patch.object(ControlServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceClient)) +@mock.patch.object(ControlServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ControlServiceAsyncClient)) +def test_control_service_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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc"), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest"), +]) +def test_control_service_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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", grpc_helpers), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ControlServiceClient, transports.ControlServiceRestTransport, "rest", None), +]) +def test_control_service_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_control_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.control_service.transports.ControlServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ControlServiceClient( + 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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport, "grpc", grpc_helpers), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_control_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.CreateControlRequest, + dict, +]) +def test_create_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.create_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_create_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.create_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + +@pytest.mark.asyncio +async def test_create_control_async(transport: str = 'grpc_asyncio', request_type=control_service.CreateControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.create_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.CreateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_create_control_async_from_dict(): + await test_create_control_async(request_type=dict) + + +def test_create_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.CreateControlRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + call.return_value = gcr_control.Control() + client.create_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.CreateControlRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + await client.create_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_control( + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))) + assert arg == mock_val + arg = args[0].control_id + mock_val = 'control_id_value' + assert arg == mock_val + + +def test_create_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + +@pytest.mark.asyncio +async def test_create_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_control( + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))) + assert arg == mock_val + arg = args[0].control_id + mock_val = 'control_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.DeleteControlRequest, + dict, +]) +def test_delete_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.delete_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + +@pytest.mark.asyncio +async def test_delete_control_async(transport: str = 'grpc_asyncio', request_type=control_service.DeleteControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.DeleteControlRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_control_async_from_dict(): + await test_delete_control_async(request_type=dict) + + +def test_delete_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.DeleteControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__call__') as call: + call.return_value = None + client.delete_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.DeleteControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__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_control( + 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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_control), + '__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_control( + 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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.UpdateControlRequest, + dict, +]) +def test_update_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.update_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_update_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.update_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + +@pytest.mark.asyncio +async def test_update_control_async(transport: str = 'grpc_asyncio', request_type=control_service.UpdateControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.update_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.UpdateControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_update_control_async_from_dict(): + await test_update_control_async(request_type=dict) + + +def test_update_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.UpdateControlRequest() + + request.control.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + call.return_value = gcr_control.Control() + client.update_control(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', + 'control.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.UpdateControlRequest() + + request.control.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + await client.update_control(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', + 'control.name=name_value', + ) in kw['metadata'] + + +def test_update_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_control( + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_control( + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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].control + mock_val = gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.GetControlRequest, + dict, +]) +def test_get_control(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + response = client.get_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_get_control_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 = ControlServiceClient( + 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_control), + '__call__') as call: + client.get_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + +@pytest.mark.asyncio +async def test_get_control_async(transport: str = 'grpc_asyncio', request_type=control_service.GetControlRequest): + client = ControlServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + )) + response = await client.get_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.GetControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +@pytest.mark.asyncio +async def test_get_control_async_from_dict(): + await test_get_control_async(request_type=dict) + + +def test_get_control_field_headers(): + client = ControlServiceClient( + 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 = control_service.GetControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + call.return_value = control.Control() + client.get_control(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_control_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.GetControlRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control.Control()) + await client.get_control(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_control_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_control( + 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_control_flattened_error(): + client = ControlServiceClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_control_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control.Control() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control.Control()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_control( + 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_control_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.ListControlsRequest, + dict, +]) +def test_list_controls(request_type, transport: str = 'grpc'): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_controls(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_controls_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 = ControlServiceClient( + 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_controls), + '__call__') as call: + client.list_controls() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + +@pytest.mark.asyncio +async def test_list_controls_async(transport: str = 'grpc_asyncio', request_type=control_service.ListControlsRequest): + client = ControlServiceAsyncClient( + 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_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_controls(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == control_service.ListControlsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_controls_async_from_dict(): + await test_list_controls_async(request_type=dict) + + +def test_list_controls_field_headers(): + client = ControlServiceClient( + 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 = control_service.ListControlsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + call.return_value = control_service.ListControlsResponse() + client.list_controls(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_controls_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = control_service.ListControlsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse()) + await client.list_controls(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_controls_flattened(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_controls( + 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_controls_flattened_error(): + client = ControlServiceClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_controls_flattened_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = control_service.ListControlsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(control_service.ListControlsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_controls( + 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_controls_flattened_error_async(): + client = ControlServiceAsyncClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + + +def test_list_controls_pager(transport_name: str = "grpc"): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_controls(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, control.Control) + for i in results) +def test_list_controls_pages(transport_name: str = "grpc"): + client = ControlServiceClient( + 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_controls), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + pages = list(client.list_controls(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_controls_async_pager(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_controls(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, control.Control) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_controls_async_pages(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_controls), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + 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_controls(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", [ + control_service.CreateControlRequest, + dict, +]) +def test_create_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'name_value', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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 = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_create_control_rest_required_fields(request_type=control_service.CreateControlRequest): + transport_class = transports.ControlServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["control_id"] = "" + 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 + assert "controlId" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == request_init["control_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_control._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("control_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' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_control.Control() + # 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 + + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_control(request) + + expected_params = [ + ( + "controlId", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(("controlId", )) & set(("parent", "control", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_create_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_create_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.CreateControlRequest.pb(control_service.CreateControlRequest()) + 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 = gcr_control.Control.to_json(gcr_control.Control()) + + request = control_service.CreateControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_control.Control() + + client.create_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_control_rest_bad_request(transport: str = 'rest', request_type=control_service.CreateControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'name_value', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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_control(request) + + +def test_create_control_rest_flattened(): + client = ControlServiceClient( + 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 = gcr_control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_control(**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/v2beta/{parent=projects/*/locations/*/catalogs/*}/controls" % client.transport._host, args[1]) + + +def test_create_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.CreateControlRequest(), + parent='parent_value', + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + control_id='control_id_value', + ) + + +def test_create_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.DeleteControlRequest, + dict, +]) +def test_delete_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_control_rest_required_fields(request_type=control_service.DeleteControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + 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_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "pre_delete_control") as pre: + pre.assert_not_called() + pb_message = control_service.DeleteControlRequest.pb(control_service.DeleteControlRequest()) + 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 = control_service.DeleteControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_control_rest_bad_request(transport: str = 'rest', request_type=control_service.DeleteControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + +def test_delete_control_rest_flattened(): + client = ControlServiceClient( + 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/catalogs/sample3/controls/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_control(**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/v2beta/{name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_delete_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.DeleteControlRequest(), + name='name_value', + ) + + +def test_delete_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.UpdateControlRequest, + dict, +]) +def test_update_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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 = gcr_control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_update_control_rest_required_fields(request_type=control_service.UpdateControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_control.Control() + # 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 + + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("control", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_update_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_update_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.UpdateControlRequest.pb(control_service.UpdateControlRequest()) + 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 = gcr_control.Control.to_json(gcr_control.Control()) + + request = control_service.UpdateControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_control.Control() + + client.update_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_control_rest_bad_request(transport: str = 'rest', request_type=control_service.UpdateControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + request_init["control"] = {'facet_spec': {'facet_key': {'key': 'key_value', 'intervals': [{'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}], 'restricted_values': ['restricted_values_value1', 'restricted_values_value2'], 'prefixes': ['prefixes_value1', 'prefixes_value2'], 'contains': ['contains_value1', 'contains_value2'], 'case_insensitive': True, 'order_by': 'order_by_value', 'query': 'query_value', 'return_min_max': True}, 'limit': 543, 'excluded_filter_keys': ['excluded_filter_keys_value1', 'excluded_filter_keys_value2'], 'enable_dynamic_position': True}, 'rule': {'boost_action': {'boost': 0.551, 'products_filter': 'products_filter_value'}, 'redirect_action': {'redirect_uri': 'redirect_uri_value'}, 'oneway_synonyms_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'synonyms': ['synonyms_value1', 'synonyms_value2'], 'oneway_terms': ['oneway_terms_value1', 'oneway_terms_value2']}, 'do_not_associate_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'do_not_associate_terms': ['do_not_associate_terms_value1', 'do_not_associate_terms_value2'], 'terms': ['terms_value1', 'terms_value2']}, 'replacement_action': {'query_terms': ['query_terms_value1', 'query_terms_value2'], 'replacement_term': 'replacement_term_value', 'term': 'term_value'}, 'ignore_action': {'ignore_terms': ['ignore_terms_value1', 'ignore_terms_value2']}, 'filter_action': {'filter': 'filter_value'}, 'twoway_synonyms_action': {'synonyms': ['synonyms_value1', 'synonyms_value2']}, 'condition': {'query_terms': [{'value': 'value_value', 'full_match': True}], 'active_time_range': [{'start_time': {'seconds': 751, 'nanos': 543}, 'end_time': {}}]}}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4', 'display_name': 'display_name_value', 'associated_serving_config_ids': ['associated_serving_config_ids_value1', 'associated_serving_config_ids_value2'], 'solution_types': [1], 'search_solution_use_case': [1]} + 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_control(request) + + +def test_update_control_rest_flattened(): + client = ControlServiceClient( + 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 = gcr_control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'control': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_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 + pb_return_value = gcr_control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_control(**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/v2beta/{control.name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_update_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.UpdateControlRequest(), + control=gcr_control.Control(facet_spec=search_service.SearchRequest.FacetSpec(facet_key=search_service.SearchRequest.FacetSpec.FacetKey(key='key_value'))), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.GetControlRequest, + dict, +]) +def test_get_control_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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 = control.Control( + name='name_value', + display_name='display_name_value', + associated_serving_config_ids=['associated_serving_config_ids_value'], + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + search_solution_use_case=[common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, control.Control) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.associated_serving_config_ids == ['associated_serving_config_ids_value'] + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + assert response.search_solution_use_case == [common.SearchSolutionUseCase.SEARCH_SOLUTION_USE_CASE_SEARCH] + + +def test_get_control_rest_required_fields(request_type=control_service.GetControlRequest): + transport_class = transports.ControlServiceRestTransport + + 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_control._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_control._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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = control.Control() + # 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 + + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_control_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_control_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_get_control") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_get_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.GetControlRequest.pb(control_service.GetControlRequest()) + 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 = control.Control.to_json(control.Control()) + + request = control_service.GetControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = control.Control() + + client.get_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_control_rest_bad_request(transport: str = 'rest', request_type=control_service.GetControlRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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_control(request) + + +def test_get_control_rest_flattened(): + client = ControlServiceClient( + 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 = control.Control() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/controls/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 + pb_return_value = control.Control.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_control(**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/v2beta/{name=projects/*/locations/*/catalogs/*/controls/*}" % client.transport._host, args[1]) + + +def test_get_control_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_control( + control_service.GetControlRequest(), + name='name_value', + ) + + +def test_get_control_rest_error(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + control_service.ListControlsRequest, + dict, +]) +def test_list_controls_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = control_service.ListControlsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_controls(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListControlsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_controls_rest_required_fields(request_type=control_service.ListControlsRequest): + transport_class = transports.ControlServiceRestTransport + + 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_controls._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_controls._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("filter", "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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = control_service.ListControlsResponse() + # 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 + + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_controls(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_controls_rest_unset_required_fields(): + transport = transports.ControlServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_controls._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_controls_rest_interceptors(null_interceptor): + transport = transports.ControlServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ControlServiceRestInterceptor(), + ) + client = ControlServiceClient(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.ControlServiceRestInterceptor, "post_list_controls") as post, \ + mock.patch.object(transports.ControlServiceRestInterceptor, "pre_list_controls") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = control_service.ListControlsRequest.pb(control_service.ListControlsRequest()) + 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 = control_service.ListControlsResponse.to_json(control_service.ListControlsResponse()) + + request = control_service.ListControlsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = control_service.ListControlsResponse() + + client.list_controls(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_controls_rest_bad_request(transport: str = 'rest', request_type=control_service.ListControlsRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_controls(request) + + +def test_list_controls_rest_flattened(): + client = ControlServiceClient( + 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 = control_service.ListControlsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = control_service.ListControlsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_controls(**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/v2beta/{parent=projects/*/locations/*/catalogs/*}/controls" % client.transport._host, args[1]) + + +def test_list_controls_rest_flattened_error(transport: str = 'rest'): + client = ControlServiceClient( + 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_controls( + control_service.ListControlsRequest(), + parent='parent_value', + ) + + +def test_list_controls_rest_pager(transport: str = 'rest'): + client = ControlServiceClient( + 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 = ( + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + control.Control(), + ], + next_page_token='abc', + ), + control_service.ListControlsResponse( + controls=[], + next_page_token='def', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + ], + next_page_token='ghi', + ), + control_service.ListControlsResponse( + controls=[ + control.Control(), + control.Control(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(control_service.ListControlsResponse.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/catalogs/sample3'} + + pager = client.list_controls(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, control.Control) + for i in results) + + pages = list(client.list_controls(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ControlServiceClient( + 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 = ControlServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ControlServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ControlServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ControlServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ControlServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + transports.ControlServiceRestTransport, +]) +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 = ControlServiceClient.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 = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ControlServiceGrpcTransport, + ) + +def test_control_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ControlServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_control_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.control_service.transports.ControlServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ControlServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_control', + 'delete_control', + 'update_control', + 'get_control', + 'list_controls', + 'get_operation', + 'list_operations', + ) + 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_control_service_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.retail_v2beta.services.control_service.transports.ControlServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ControlServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_control_service_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.retail_v2beta.services.control_service.transports.ControlServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ControlServiceTransport() + adc.assert_called_once() + + +def test_control_service_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) + ControlServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + ], +) +def test_control_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ControlServiceGrpcTransport, + transports.ControlServiceGrpcAsyncIOTransport, + transports.ControlServiceRestTransport, + ], +) +def test_control_service_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.ControlServiceGrpcTransport, grpc_helpers), + (transports.ControlServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_control_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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_control_service_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.ControlServiceRestTransport ( + 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_control_service_host_no_port(transport_name): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_control_service_host_with_port(transport_name): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_control_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ControlServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ControlServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_control._session + session2 = client2.transport.create_control._session + assert session1 != session2 + session1 = client1.transport.delete_control._session + session2 = client2.transport.delete_control._session + assert session1 != session2 + session1 = client1.transport.update_control._session + session2 = client2.transport.update_control._session + assert session1 != session2 + session1 = client1.transport.get_control._session + session2 = client2.transport.get_control._session + assert session1 != session2 + session1 = client1.transport.list_controls._session + session2 = client2.transport.list_controls._session + assert session1 != session2 +def test_control_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ControlServiceGrpcTransport( + 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_control_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ControlServiceGrpcAsyncIOTransport( + 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.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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.ControlServiceGrpcTransport, transports.ControlServiceGrpcAsyncIOTransport]) +def test_control_service_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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ControlServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ControlServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_control_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + control = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/controls/{control}".format(project=project, location=location, catalog=catalog, control=control, ) + actual = ControlServiceClient.control_path(project, location, catalog, control) + assert expected == actual + + +def test_parse_control_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "control": "clam", + } + path = ControlServiceClient.control_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_control_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ControlServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ControlServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ControlServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ControlServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ControlServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ControlServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ControlServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ControlServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ControlServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ControlServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ControlServiceClient.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.ControlServiceTransport, '_prep_wrapped_messages') as prep: + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ControlServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ControlServiceClient.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 = ControlServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ControlServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ControlServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ControlServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ControlServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ControlServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ControlServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ControlServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ControlServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ControlServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ControlServiceClient( + 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 = ControlServiceClient( + 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", [ + (ControlServiceClient, transports.ControlServiceGrpcTransport), + (ControlServiceAsyncClient, transports.ControlServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_model_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_model_service.py new file mode 100644 index 00000000..87ac9658 --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_model_service.py @@ -0,0 +1,5874 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.model_service import ModelServiceAsyncClient +from google.cloud.retail_v2beta.services.model_service import ModelServiceClient +from google.cloud.retail_v2beta.services.model_service import pagers +from google.cloud.retail_v2beta.services.model_service import transports +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import model +from google.cloud.retail_v2beta.types import model as gcr_model +from google.cloud.retail_v2beta.types import model_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_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 ModelServiceClient._get_default_mtls_endpoint(None) is None + assert ModelServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ModelServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), +]) +def test_model_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ModelServiceGrpcTransport, "grpc"), + (transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ModelServiceRestTransport, "rest"), +]) +def test_model_service_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", [ + (ModelServiceClient, "grpc"), + (ModelServiceAsyncClient, "grpc_asyncio"), + (ModelServiceClient, "rest"), +]) +def test_model_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_model_service_client_get_transport_class(): + transport = ModelServiceClient.get_transport_class() + available_transports = [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceRestTransport, + ] + assert transport in available_transports + + transport = ModelServiceClient.get_transport_class("grpc") + assert transport == transports.ModelServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +def test_model_service_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(ModelServiceClient, '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(ModelServiceClient, '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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "true"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", "false"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "true"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_model_service_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", [ + ModelServiceClient, ModelServiceAsyncClient +]) +@mock.patch.object(ModelServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceClient)) +@mock.patch.object(ModelServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ModelServiceAsyncClient)) +def test_model_service_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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc"), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest"), +]) +def test_model_service_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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", grpc_helpers), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ModelServiceClient, transports.ModelServiceRestTransport, "rest", None), +]) +def test_model_service_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_model_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.model_service.transports.ModelServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ModelServiceClient( + 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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport, "grpc", grpc_helpers), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_model_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.CreateModelRequest, + dict, +]) +def test_create_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_create_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.create_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + +@pytest.mark.asyncio +async def test_create_model_async(transport: str = 'grpc_asyncio', request_type=model_service.CreateModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__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.create_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.CreateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_create_model_async_from_dict(): + await test_create_model_async(request_type=dict) + + +def test_create_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.CreateModelRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.create_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.CreateModelRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.create_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__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.create_model( + parent='parent_value', + model=gcr_model.Model(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].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].model + mock_val = gcr_model.Model(name='name_value') + assert arg == mock_val + + +def test_create_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(name='name_value'), + ) + +@pytest.mark.asyncio +async def test_create_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_model), + '__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.create_model( + parent='parent_value', + model=gcr_model.Model(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].parent + mock_val = 'parent_value' + assert arg == mock_val + arg = args[0].model + mock_val = gcr_model.Model(name='name_value') + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(name='name_value'), + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.GetModelRequest, + dict, +]) +def test_get_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_get_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.get_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + +@pytest.mark.asyncio +async def test_get_model_async(transport: str = 'grpc_asyncio', request_type=model_service.GetModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.get_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.GetModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_get_model_async_from_dict(): + await test_get_model_async(request_type=dict) + + +def test_get_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.GetModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + call.return_value = model.Model() + client.get_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.GetModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.get_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_model( + 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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_model( + 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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.PauseModelRequest, + dict, +]) +def test_pause_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_pause_model_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 = ModelServiceClient( + 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.pause_model), + '__call__') as call: + client.pause_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + +@pytest.mark.asyncio +async def test_pause_model_async(transport: str = 'grpc_asyncio', request_type=model_service.PauseModelRequest): + client = ModelServiceAsyncClient( + 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.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.pause_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.PauseModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_pause_model_async_from_dict(): + await test_pause_model_async(request_type=dict) + + +def test_pause_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.PauseModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + call.return_value = model.Model() + client.pause_model(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_pause_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.PauseModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.pause_model(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_pause_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.pause_model( + 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_pause_model_flattened_error(): + client = ModelServiceClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_pause_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.pause_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.pause_model( + 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_pause_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ResumeModelRequest, + dict, +]) +def test_resume_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_resume_model_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 = ModelServiceClient( + 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.resume_model), + '__call__') as call: + client.resume_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + +@pytest.mark.asyncio +async def test_resume_model_async(transport: str = 'grpc_asyncio', request_type=model_service.ResumeModelRequest): + client = ModelServiceAsyncClient( + 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.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.resume_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ResumeModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_resume_model_async_from_dict(): + await test_resume_model_async(request_type=dict) + + +def test_resume_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.ResumeModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + call.return_value = model.Model() + client.resume_model(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_resume_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.ResumeModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + await client.resume_model(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_resume_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.resume_model( + 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_resume_model_flattened_error(): + client = ModelServiceClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_resume_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.resume_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.resume_model( + 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_resume_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.DeleteModelRequest, + dict, +]) +def test_delete_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.delete_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + +@pytest.mark.asyncio +async def test_delete_model_async(transport: str = 'grpc_asyncio', request_type=model_service.DeleteModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.DeleteModelRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_model_async_from_dict(): + await test_delete_model_async(request_type=dict) + + +def test_delete_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.DeleteModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__call__') as call: + call.return_value = None + client.delete_model(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_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.DeleteModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_model(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_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__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_model( + 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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_model), + '__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_model( + 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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ListModelsRequest, + dict, +]) +def test_list_models(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_models_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 = ModelServiceClient( + 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_models), + '__call__') as call: + client.list_models() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + +@pytest.mark.asyncio +async def test_list_models_async(transport: str = 'grpc_asyncio', request_type=model_service.ListModelsRequest): + client = ModelServiceAsyncClient( + 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_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_models(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.ListModelsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_models_async_from_dict(): + await test_list_models_async(request_type=dict) + + +def test_list_models_field_headers(): + client = ModelServiceClient( + 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 = model_service.ListModelsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + call.return_value = model_service.ListModelsResponse() + client.list_models(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_models_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.ListModelsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse()) + await client.list_models(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_models_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_models( + 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_models_flattened_error(): + client = ModelServiceClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_models_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = model_service.ListModelsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(model_service.ListModelsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_models( + 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_models_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + + +def test_list_models_pager(transport_name: str = "grpc"): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_models(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) + for i in results) +def test_list_models_pages(transport_name: str = "grpc"): + client = ModelServiceClient( + 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_models), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + pages = list(client.list_models(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_models_async_pager(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_models(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, model.Model) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_models_async_pages(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_models), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + 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_models(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", [ + model_service.UpdateModelRequest, + dict, +]) +def test_update_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + response = client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_update_model_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 = ModelServiceClient( + 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_model), + '__call__') as call: + client.update_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + +@pytest.mark.asyncio +async def test_update_model_async(transport: str = 'grpc_asyncio', request_type=model_service.UpdateModelRequest): + client = ModelServiceAsyncClient( + 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_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + )) + response = await client.update_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.UpdateModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +@pytest.mark.asyncio +async def test_update_model_async_from_dict(): + await test_update_model_async(request_type=dict) + + +def test_update_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.UpdateModelRequest() + + request.model.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + call.return_value = gcr_model.Model() + client.update_model(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', + 'model.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.UpdateModelRequest() + + request.model.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + await client.update_model(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', + 'model.name=name_value', + ) in kw['metadata'] + + +def test_update_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_model( + model=gcr_model.Model(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].model + mock_val = gcr_model.Model(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_model_flattened_error(): + client = ModelServiceClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_model.Model() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_model.Model()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_model( + model=gcr_model.Model(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].model + mock_val = gcr_model.Model(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_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.TuneModelRequest, + dict, +]) +def test_tune_model(request_type, transport: str = 'grpc'): + client = ModelServiceClient( + 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.tune_model), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_tune_model_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 = ModelServiceClient( + 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.tune_model), + '__call__') as call: + client.tune_model() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + +@pytest.mark.asyncio +async def test_tune_model_async(transport: str = 'grpc_asyncio', request_type=model_service.TuneModelRequest): + client = ModelServiceAsyncClient( + 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.tune_model), + '__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.tune_model(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == model_service.TuneModelRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_tune_model_async_from_dict(): + await test_tune_model_async(request_type=dict) + + +def test_tune_model_field_headers(): + client = ModelServiceClient( + 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 = model_service.TuneModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.tune_model(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_tune_model_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = model_service.TuneModelRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.tune_model(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_tune_model_flattened(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__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.tune_model( + 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_tune_model_flattened_error(): + client = ModelServiceClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_tune_model_flattened_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.tune_model), + '__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.tune_model( + 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_tune_model_flattened_error_async(): + client = ModelServiceAsyncClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.CreateModelRequest, + dict, +]) +def test_create_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["model"] = {'name': 'name_value', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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.create_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_create_model_rest_required_fields(request_type=model_service.CreateModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("dry_run", )) + 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 = ModelServiceClient( + 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.create_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(("dryRun", )) & set(("parent", "model", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_create_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_create_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.CreateModelRequest.pb(model_service.CreateModelRequest()) + 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 = model_service.CreateModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.create_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_model_rest_bad_request(transport: str = 'rest', request_type=model_service.CreateModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["model"] = {'name': 'name_value', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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_model(request) + + +def test_create_model_rest_flattened(): + client = ModelServiceClient( + 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/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + model=gcr_model.Model(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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_model(**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/v2beta/{parent=projects/*/locations/*/catalogs/*}/models" % client.transport._host, args[1]) + + +def test_create_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.CreateModelRequest(), + parent='parent_value', + model=gcr_model.Model(name='name_value'), + ) + + +def test_create_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.GetModelRequest, + dict, +]) +def test_get_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_get_model_rest_required_fields(request_type=model_service.GetModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_get_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_get_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.GetModelRequest.pb(model_service.GetModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.GetModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.get_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_model_rest_bad_request(transport: str = 'rest', request_type=model_service.GetModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + +def test_get_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_model(**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/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_get_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.GetModelRequest(), + name='name_value', + ) + + +def test_get_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.PauseModelRequest, + dict, +]) +def test_pause_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.pause_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_pause_model_rest_required_fields(request_type=model_service.PauseModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).pause_model._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()).pause_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.pause_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_pause_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.pause_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_pause_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_pause_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_pause_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.PauseModelRequest.pb(model_service.PauseModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.PauseModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.pause_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_pause_model_rest_bad_request(transport: str = 'rest', request_type=model_service.PauseModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.pause_model(request) + + +def test_pause_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.pause_model(**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/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}:pause" % client.transport._host, args[1]) + + +def test_pause_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.pause_model( + model_service.PauseModelRequest(), + name='name_value', + ) + + +def test_pause_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ResumeModelRequest, + dict, +]) +def test_resume_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = model.Model( + name='name_value', + display_name='display_name_value', + training_state=model.Model.TrainingState.PAUSED, + serving_state=model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.resume_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == model.Model.TrainingState.PAUSED + assert response.serving_state == model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_resume_model_rest_required_fields(request_type=model_service.ResumeModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).resume_model._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()).resume_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model.Model() + # 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 + + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.resume_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_resume_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.resume_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_resume_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_resume_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_resume_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ResumeModelRequest.pb(model_service.ResumeModelRequest()) + 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 = model.Model.to_json(model.Model()) + + request = model_service.ResumeModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model.Model() + + client.resume_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_resume_model_rest_bad_request(transport: str = 'rest', request_type=model_service.ResumeModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.resume_model(request) + + +def test_resume_model_rest_flattened(): + client = ModelServiceClient( + 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 = model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 + pb_return_value = model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.resume_model(**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/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}:resume" % client.transport._host, args[1]) + + +def test_resume_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.resume_model( + model_service.ResumeModelRequest(), + name='name_value', + ) + + +def test_resume_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.DeleteModelRequest, + dict, +]) +def test_delete_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_model_rest_required_fields(request_type=model_service.DeleteModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + 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_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "pre_delete_model") as pre: + pre.assert_not_called() + pb_message = model_service.DeleteModelRequest.pb(model_service.DeleteModelRequest()) + 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 = model_service.DeleteModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_model_rest_bad_request(transport: str = 'rest', request_type=model_service.DeleteModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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_model(request) + + +def test_delete_model_rest_flattened(): + client = ModelServiceClient( + 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/catalogs/sample3/models/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_model(**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/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_delete_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.DeleteModelRequest(), + name='name_value', + ) + + +def test_delete_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.ListModelsRequest, + dict, +]) +def test_list_models_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = model_service.ListModelsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_models(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListModelsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_models_rest_required_fields(request_type=model_service.ListModelsRequest): + transport_class = transports.ModelServiceRestTransport + + 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_models._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_models._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = model_service.ListModelsResponse() + # 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 + + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_models(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_models_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_models._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_models_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_list_models") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_list_models") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.ListModelsRequest.pb(model_service.ListModelsRequest()) + 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 = model_service.ListModelsResponse.to_json(model_service.ListModelsResponse()) + + request = model_service.ListModelsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = model_service.ListModelsResponse() + + client.list_models(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_models_rest_bad_request(transport: str = 'rest', request_type=model_service.ListModelsRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_models(request) + + +def test_list_models_rest_flattened(): + client = ModelServiceClient( + 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 = model_service.ListModelsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = model_service.ListModelsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_models(**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/v2beta/{parent=projects/*/locations/*/catalogs/*}/models" % client.transport._host, args[1]) + + +def test_list_models_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_models( + model_service.ListModelsRequest(), + parent='parent_value', + ) + + +def test_list_models_rest_pager(transport: str = 'rest'): + client = ModelServiceClient( + 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 = ( + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + model.Model(), + ], + next_page_token='abc', + ), + model_service.ListModelsResponse( + models=[], + next_page_token='def', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + ], + next_page_token='ghi', + ), + model_service.ListModelsResponse( + models=[ + model.Model(), + model.Model(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(model_service.ListModelsResponse.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/catalogs/sample3'} + + pager = client.list_models(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, model.Model) + for i in results) + + pages = list(client.list_models(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", [ + model_service.UpdateModelRequest, + dict, +]) +def test_update_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + request_init["model"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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 = gcr_model.Model( + name='name_value', + display_name='display_name_value', + training_state=gcr_model.Model.TrainingState.PAUSED, + serving_state=gcr_model.Model.ServingState.INACTIVE, + type_='type__value', + optimization_objective='optimization_objective_value', + periodic_tuning_state=gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED, + tuning_operation='tuning_operation_value', + data_state=gcr_model.Model.DataState.DATA_OK, + filtering_option=common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_model(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_model.Model) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.training_state == gcr_model.Model.TrainingState.PAUSED + assert response.serving_state == gcr_model.Model.ServingState.INACTIVE + assert response.type_ == 'type__value' + assert response.optimization_objective == 'optimization_objective_value' + assert response.periodic_tuning_state == gcr_model.Model.PeriodicTuningState.PERIODIC_TUNING_DISABLED + assert response.tuning_operation == 'tuning_operation_value' + assert response.data_state == gcr_model.Model.DataState.DATA_OK + assert response.filtering_option == common.RecommendationsFilteringOption.RECOMMENDATIONS_FILTERING_DISABLED + + +def test_update_model_rest_required_fields(request_type=model_service.UpdateModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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_model._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_model._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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_model.Model() + # 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 + + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("model", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_update_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_update_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.UpdateModelRequest.pb(model_service.UpdateModelRequest()) + 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 = gcr_model.Model.to_json(gcr_model.Model()) + + request = model_service.UpdateModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_model.Model() + + client.update_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_model_rest_bad_request(transport: str = 'rest', request_type=model_service.UpdateModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + request_init["model"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4', 'display_name': 'display_name_value', 'training_state': 1, 'serving_state': 1, 'create_time': {'seconds': 751, 'nanos': 543}, 'update_time': {}, 'type_': 'type__value', 'optimization_objective': 'optimization_objective_value', 'periodic_tuning_state': 1, 'last_tune_time': {}, 'tuning_operation': 'tuning_operation_value', 'data_state': 1, 'filtering_option': 1, 'serving_config_lists': [{'serving_config_ids': ['serving_config_ids_value1', 'serving_config_ids_value2']}]} + 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_model(request) + + +def test_update_model_rest_flattened(): + client = ModelServiceClient( + 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 = gcr_model.Model() + + # get arguments that satisfy an http rule for this method + sample_request = {'model': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + model=gcr_model.Model(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 + pb_return_value = gcr_model.Model.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_model(**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/v2beta/{model.name=projects/*/locations/*/catalogs/*/models/*}" % client.transport._host, args[1]) + + +def test_update_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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_model( + model_service.UpdateModelRequest(), + model=gcr_model.Model(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + model_service.TuneModelRequest, + dict, +]) +def test_tune_model_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = 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.tune_model(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_tune_model_rest_required_fields(request_type=model_service.TuneModelRequest): + transport_class = transports.ModelServiceRestTransport + + 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()).tune_model._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()).tune_model._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 = ModelServiceClient( + 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.tune_model(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_tune_model_rest_unset_required_fields(): + transport = transports.ModelServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.tune_model._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_tune_model_rest_interceptors(null_interceptor): + transport = transports.ModelServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ModelServiceRestInterceptor(), + ) + client = ModelServiceClient(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.ModelServiceRestInterceptor, "post_tune_model") as post, \ + mock.patch.object(transports.ModelServiceRestInterceptor, "pre_tune_model") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = model_service.TuneModelRequest.pb(model_service.TuneModelRequest()) + 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 = model_service.TuneModelRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.tune_model(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_tune_model_rest_bad_request(transport: str = 'rest', request_type=model_service.TuneModelRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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.tune_model(request) + + +def test_tune_model_rest_flattened(): + client = ModelServiceClient( + 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 = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/models/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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.tune_model(**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/v2beta/{name=projects/*/locations/*/catalogs/*/models/*}:tune" % client.transport._host, args[1]) + + +def test_tune_model_rest_flattened_error(transport: str = 'rest'): + client = ModelServiceClient( + 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.tune_model( + model_service.TuneModelRequest(), + name='name_value', + ) + + +def test_tune_model_rest_error(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ModelServiceClient( + 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 = ModelServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ModelServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ModelServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ModelServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ModelServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, +]) +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 = ModelServiceClient.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 = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ModelServiceGrpcTransport, + ) + +def test_model_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_model_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.model_service.transports.ModelServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ModelServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_model', + 'get_model', + 'pause_model', + 'resume_model', + 'delete_model', + 'list_models', + 'update_model', + 'tune_model', + 'get_operation', + 'list_operations', + ) + 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_model_service_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.retail_v2beta.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_model_service_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.retail_v2beta.services.model_service.transports.ModelServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ModelServiceTransport() + adc.assert_called_once() + + +def test_model_service_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) + ModelServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + ], +) +def test_model_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ModelServiceGrpcTransport, + transports.ModelServiceGrpcAsyncIOTransport, + transports.ModelServiceRestTransport, + ], +) +def test_model_service_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.ModelServiceGrpcTransport, grpc_helpers), + (transports.ModelServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_model_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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_model_service_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.ModelServiceRestTransport ( + 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_model_service_rest_lro_client(): + client = ModelServiceClient( + 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_model_service_host_no_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_model_service_host_with_port(transport_name): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_model_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ModelServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ModelServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_model._session + session2 = client2.transport.create_model._session + assert session1 != session2 + session1 = client1.transport.get_model._session + session2 = client2.transport.get_model._session + assert session1 != session2 + session1 = client1.transport.pause_model._session + session2 = client2.transport.pause_model._session + assert session1 != session2 + session1 = client1.transport.resume_model._session + session2 = client2.transport.resume_model._session + assert session1 != session2 + session1 = client1.transport.delete_model._session + session2 = client2.transport.delete_model._session + assert session1 != session2 + session1 = client1.transport.list_models._session + session2 = client2.transport.list_models._session + assert session1 != session2 + session1 = client1.transport.update_model._session + session2 = client2.transport.update_model._session + assert session1 != session2 + session1 = client1.transport.tune_model._session + session2 = client2.transport.tune_model._session + assert session1 != session2 +def test_model_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcTransport( + 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_model_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ModelServiceGrpcAsyncIOTransport( + 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.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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.ModelServiceGrpcTransport, transports.ModelServiceGrpcAsyncIOTransport]) +def test_model_service_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_model_service_grpc_lro_client(): + client = ModelServiceClient( + 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_model_service_grpc_lro_async_client(): + client = ModelServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ModelServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ModelServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_model_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + model = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/models/{model}".format(project=project, location=location, catalog=catalog, model=model, ) + actual = ModelServiceClient.model_path(project, location, catalog, model) + assert expected == actual + + +def test_parse_model_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "model": "clam", + } + path = ModelServiceClient.model_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_model_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ModelServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ModelServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ModelServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ModelServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ModelServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ModelServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ModelServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ModelServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ModelServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ModelServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ModelServiceClient.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.ModelServiceTransport, '_prep_wrapped_messages') as prep: + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ModelServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ModelServiceClient.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 = ModelServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ModelServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ModelServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ModelServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ModelServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ModelServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ModelServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ModelServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ModelServiceClient( + 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 = ModelServiceClient( + 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", [ + (ModelServiceClient, transports.ModelServiceGrpcTransport), + (ModelServiceAsyncClient, transports.ModelServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_prediction_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_prediction_service.py new file mode 100644 index 00000000..6e589ed2 --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_prediction_service.py @@ -0,0 +1,1931 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.prediction_service import PredictionServiceAsyncClient +from google.cloud.retail_v2beta.services.prediction_service import PredictionServiceClient +from google.cloud.retail_v2beta.services.prediction_service import transports +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import prediction_service +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import promotion +from google.cloud.retail_v2beta.types import user_event +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import struct_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_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 PredictionServiceClient._get_default_mtls_endpoint(None) is None + assert PredictionServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert PredictionServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (PredictionServiceClient, "grpc"), + (PredictionServiceAsyncClient, "grpc_asyncio"), + (PredictionServiceClient, "rest"), +]) +def test_prediction_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.PredictionServiceGrpcTransport, "grpc"), + (transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.PredictionServiceRestTransport, "rest"), +]) +def test_prediction_service_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", [ + (PredictionServiceClient, "grpc"), + (PredictionServiceAsyncClient, "grpc_asyncio"), + (PredictionServiceClient, "rest"), +]) +def test_prediction_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_prediction_service_client_get_transport_class(): + transport = PredictionServiceClient.get_transport_class() + available_transports = [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceRestTransport, + ] + assert transport in available_transports + + transport = PredictionServiceClient.get_transport_class("grpc") + assert transport == transports.PredictionServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_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(PredictionServiceClient, '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(PredictionServiceClient, '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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "true"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", "false"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", "true"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_prediction_service_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", [ + PredictionServiceClient, PredictionServiceAsyncClient +]) +@mock.patch.object(PredictionServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceClient)) +@mock.patch.object(PredictionServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(PredictionServiceAsyncClient)) +def test_prediction_service_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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc"), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest"), +]) +def test_prediction_service_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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", grpc_helpers), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (PredictionServiceClient, transports.PredictionServiceRestTransport, "rest", None), +]) +def test_prediction_service_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_prediction_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.prediction_service.transports.PredictionServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = PredictionServiceClient( + 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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport, "grpc", grpc_helpers), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_prediction_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + prediction_service.PredictRequest, + dict, +]) +def test_predict(request_type, transport: str = 'grpc'): + client = PredictionServiceClient( + 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + ) + response = client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +def test_predict_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 = PredictionServiceClient( + 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.predict), + '__call__') as call: + client.predict() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + +@pytest.mark.asyncio +async def test_predict_async(transport: str = 'grpc_asyncio', request_type=prediction_service.PredictRequest): + client = PredictionServiceAsyncClient( + 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.predict), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + )) + response = await client.predict(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == prediction_service.PredictRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +@pytest.mark.asyncio +async def test_predict_async_from_dict(): + await test_predict_async(request_type=dict) + + +def test_predict_field_headers(): + client = PredictionServiceClient( + 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 = prediction_service.PredictRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = prediction_service.PredictResponse() + client.predict(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_predict_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = prediction_service.PredictRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.predict), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(prediction_service.PredictResponse()) + await client.predict(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.parametrize("request_type", [ + prediction_service.PredictRequest, + dict, +]) +def test_predict_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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 = prediction_service.PredictResponse( + attribution_token='attribution_token_value', + missing_ids=['missing_ids_value'], + validate_only=True, + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = prediction_service.PredictResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.predict(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, prediction_service.PredictResponse) + assert response.attribution_token == 'attribution_token_value' + assert response.missing_ids == ['missing_ids_value'] + assert response.validate_only is True + + +def test_predict_rest_required_fields(request_type=prediction_service.PredictRequest): + transport_class = transports.PredictionServiceRestTransport + + request_init = {} + request_init["placement"] = "" + 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()).predict._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["placement"] = 'placement_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).predict._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "placement" in jsonified_request + assert jsonified_request["placement"] == 'placement_value' + + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = prediction_service.PredictResponse() + # 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 + + pb_return_value = prediction_service.PredictResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.predict(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_predict_rest_unset_required_fields(): + transport = transports.PredictionServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.predict._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("placement", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_predict_rest_interceptors(null_interceptor): + transport = transports.PredictionServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.PredictionServiceRestInterceptor(), + ) + client = PredictionServiceClient(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.PredictionServiceRestInterceptor, "post_predict") as post, \ + mock.patch.object(transports.PredictionServiceRestInterceptor, "pre_predict") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = prediction_service.PredictRequest.pb(prediction_service.PredictRequest()) + 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 = prediction_service.PredictResponse.to_json(prediction_service.PredictResponse()) + + request = prediction_service.PredictRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = prediction_service.PredictResponse() + + client.predict(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_predict_rest_bad_request(transport: str = 'rest', request_type=prediction_service.PredictRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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.predict(request) + + +def test_predict_rest_error(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = PredictionServiceClient( + 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 = PredictionServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = PredictionServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = PredictionServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.PredictionServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.PredictionServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + transports.PredictionServiceRestTransport, +]) +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 = PredictionServiceClient.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 = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.PredictionServiceGrpcTransport, + ) + +def test_prediction_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_prediction_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.prediction_service.transports.PredictionServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.PredictionServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'predict', + 'get_operation', + 'list_operations', + ) + 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_prediction_service_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.retail_v2beta.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_prediction_service_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.retail_v2beta.services.prediction_service.transports.PredictionServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.PredictionServiceTransport() + adc.assert_called_once() + + +def test_prediction_service_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) + PredictionServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + ], +) +def test_prediction_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.PredictionServiceGrpcTransport, + transports.PredictionServiceGrpcAsyncIOTransport, + transports.PredictionServiceRestTransport, + ], +) +def test_prediction_service_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.PredictionServiceGrpcTransport, grpc_helpers), + (transports.PredictionServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_prediction_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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_prediction_service_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.PredictionServiceRestTransport ( + 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_prediction_service_host_no_port(transport_name): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_prediction_service_host_with_port(transport_name): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_prediction_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = PredictionServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = PredictionServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.predict._session + session2 = client2.transport.predict._session + assert session1 != session2 +def test_prediction_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcTransport( + 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_prediction_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.PredictionServiceGrpcAsyncIOTransport( + 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.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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.PredictionServiceGrpcTransport, transports.PredictionServiceGrpcAsyncIOTransport]) +def test_prediction_service_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_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + product = "oyster" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = PredictionServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "nudibranch", + "location": "cuttlefish", + "catalog": "mussel", + "branch": "winkle", + "product": "nautilus", + } + path = PredictionServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = PredictionServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = PredictionServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = PredictionServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = PredictionServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = PredictionServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = PredictionServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = PredictionServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = PredictionServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = PredictionServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = PredictionServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = PredictionServiceClient.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.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.PredictionServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = PredictionServiceClient.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 = PredictionServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = PredictionServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = PredictionServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = PredictionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = PredictionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = PredictionServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = PredictionServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = PredictionServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = PredictionServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = PredictionServiceClient( + 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 = PredictionServiceClient( + 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", [ + (PredictionServiceClient, transports.PredictionServiceGrpcTransport), + (PredictionServiceAsyncClient, transports.PredictionServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_product_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_product_service.py new file mode 100644 index 00000000..dc20bc3a --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_product_service.py @@ -0,0 +1,7266 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.product_service import ProductServiceAsyncClient +from google.cloud.retail_v2beta.services.product_service import ProductServiceClient +from google.cloud.retail_v2beta.services.product_service import pagers +from google.cloud.retail_v2beta.services.product_service import transports +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import product as gcr_product +from google.cloud.retail_v2beta.types import product_service +from google.cloud.retail_v2beta.types import promotion +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.type import date_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 ProductServiceClient._get_default_mtls_endpoint(None) is None + assert ProductServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ProductServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ProductServiceClient, "grpc"), + (ProductServiceAsyncClient, "grpc_asyncio"), + (ProductServiceClient, "rest"), +]) +def test_product_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ProductServiceGrpcTransport, "grpc"), + (transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ProductServiceRestTransport, "rest"), +]) +def test_product_service_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", [ + (ProductServiceClient, "grpc"), + (ProductServiceAsyncClient, "grpc_asyncio"), + (ProductServiceClient, "rest"), +]) +def test_product_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_product_service_client_get_transport_class(): + transport = ProductServiceClient.get_transport_class() + available_transports = [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceRestTransport, + ] + assert transport in available_transports + + transport = ProductServiceClient.get_transport_class("grpc") + assert transport == transports.ProductServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_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(ProductServiceClient, '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(ProductServiceClient, '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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "true"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", "false"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", "true"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_product_service_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", [ + ProductServiceClient, ProductServiceAsyncClient +]) +@mock.patch.object(ProductServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceClient)) +@mock.patch.object(ProductServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ProductServiceAsyncClient)) +def test_product_service_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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc"), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest"), +]) +def test_product_service_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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", grpc_helpers), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ProductServiceClient, transports.ProductServiceRestTransport, "rest", None), +]) +def test_product_service_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_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.product_service.transports.ProductServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ProductServiceClient( + 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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport, "grpc", grpc_helpers), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_product_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.CreateProductRequest, + dict, +]) +def test_create_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.CreateProductRequest() + +@pytest.mark.asyncio +async def test_create_product_async(transport: str = 'grpc_asyncio', request_type=product_service.CreateProductRequest): + client = ProductServiceAsyncClient( + 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(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.CreateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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 = gcr_product.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 = ProductServiceAsyncClient( + 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_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(gcr_product.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 = ProductServiceClient( + 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 = gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + +@pytest.mark.asyncio +async def test_create_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceAsyncClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.GetProductRequest, + dict, +]) +def test_get_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.GetProductRequest() + +@pytest.mark.asyncio +async def test_get_product_async(transport: str = 'grpc_asyncio', request_type=product_service.GetProductRequest): + client = ProductServiceAsyncClient( + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.GetProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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.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 = ProductServiceAsyncClient( + 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_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.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 = ProductServiceClient( + 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.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 = ProductServiceClient( + 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_service.GetProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_product_flattened_async(): + client = ProductServiceAsyncClient( + 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.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product.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 = ProductServiceAsyncClient( + 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_service.GetProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.ListProductsRequest, + dict, +]) +def test_list_products(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_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_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 = ProductServiceClient( + 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_service.ListProductsRequest() + +@pytest.mark.asyncio +async def test_list_products_async(transport: str = 'grpc_asyncio', request_type=product_service.ListProductsRequest): + client = ProductServiceAsyncClient( + 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_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_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 = ProductServiceClient( + 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_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_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 = ProductServiceAsyncClient( + 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_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_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 = ProductServiceClient( + 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_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 = ProductServiceClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_products_flattened_async(): + client = ProductServiceAsyncClient( + 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_service.ListProductsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(product_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 = ProductServiceAsyncClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_pager(transport_name: str = "grpc"): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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.Product) + for i in results) +def test_list_products_pages(transport_name: str = "grpc"): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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 = ProductServiceAsyncClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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.Product) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_products_async_pages(): + client = ProductServiceAsyncClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.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_service.UpdateProductRequest, + dict, +]) +def test_update_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_service.UpdateProductRequest() + +@pytest.mark.asyncio +async def test_update_product_async(transport: str = 'grpc_asyncio', request_type=product_service.UpdateProductRequest): + client = ProductServiceAsyncClient( + 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(gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_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_service.UpdateProductRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_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 = ProductServiceClient( + 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_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 = gcr_product.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 = ProductServiceAsyncClient( + 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_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(gcr_product.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 = ProductServiceClient( + 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 = gcr_product.Product() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_product( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = gcr_product.Product() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_product.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=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 = gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + 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 = ProductServiceAsyncClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.DeleteProductRequest, + dict, +]) +def test_delete_product(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_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 = ProductServiceClient( + 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_service.DeleteProductRequest() + +@pytest.mark.asyncio +async def test_delete_product_async(transport: str = 'grpc_asyncio', request_type=product_service.DeleteProductRequest): + client = ProductServiceAsyncClient( + 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_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 = ProductServiceClient( + 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_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 = ProductServiceAsyncClient( + 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_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 = ProductServiceClient( + 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 = ProductServiceClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_product_flattened_async(): + client = ProductServiceAsyncClient( + 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 = ProductServiceAsyncClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportProductsRequest, + dict, +]) +def test_import_products(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_products), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_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] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_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 = ProductServiceClient( + 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_products), + '__call__') as call: + client.import_products() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + +@pytest.mark.asyncio +async def test_import_products_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportProductsRequest): + client = ProductServiceAsyncClient( + 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_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.import_products(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportProductsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_products_async_from_dict(): + await test_import_products_async(request_type=dict) + + +def test_import_products_field_headers(): + client = ProductServiceClient( + 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 = import_config.ImportProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_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_import_products_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = import_config.ImportProductsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_products), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_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'] + + +@pytest.mark.parametrize("request_type", [ + product_service.SetInventoryRequest, + dict, +]) +def test_set_inventory(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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.set_inventory), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.set_inventory(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_service.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_set_inventory_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 = ProductServiceClient( + 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.set_inventory), + '__call__') as call: + client.set_inventory() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.SetInventoryRequest() + +@pytest.mark.asyncio +async def test_set_inventory_async(transport: str = 'grpc_asyncio', request_type=product_service.SetInventoryRequest): + client = ProductServiceAsyncClient( + 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.set_inventory), + '__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.set_inventory(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.SetInventoryRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_set_inventory_async_from_dict(): + await test_set_inventory_async(request_type=dict) + + +def test_set_inventory_field_headers(): + client = ProductServiceClient( + 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_service.SetInventoryRequest() + + request.inventory.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.set_inventory(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', + 'inventory.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_set_inventory_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.SetInventoryRequest() + + request.inventory.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.set_inventory(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', + 'inventory.name=name_value', + ) in kw['metadata'] + + +def test_set_inventory_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + + +def test_set_inventory_flattened_error(): + client = ProductServiceClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_set_inventory_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.set_inventory), + '__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.set_inventory( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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].inventory + mock_val = product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)) + assert arg == mock_val + arg = args[0].set_mask + mock_val = field_mask_pb2.FieldMask(paths=['paths_value']) + assert arg == mock_val + +@pytest.mark.asyncio +async def test_set_inventory_flattened_error_async(): + client = ProductServiceAsyncClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddFulfillmentPlacesRequest, + dict, +]) +def test_add_fulfillment_places(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.add_fulfillment_places(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_service.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_add_fulfillment_places_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 = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + client.add_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddFulfillmentPlacesRequest() + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.AddFulfillmentPlacesRequest): + client = ProductServiceAsyncClient( + 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_fulfillment_places), + '__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.add_fulfillment_places(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_async_from_dict(): + await test_add_fulfillment_places_async(request_type=dict) + + +def test_add_fulfillment_places_field_headers(): + client = ProductServiceClient( + 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_service.AddFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.add_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_fulfillment_places_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.AddFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.add_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +def test_add_fulfillment_places_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__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.add_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_fulfillment_places_flattened_error(): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_fulfillment_places_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_fulfillment_places), + '__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.add_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_fulfillment_places_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveFulfillmentPlacesRequest, + dict, +]) +def test_remove_fulfillment_places(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.remove_fulfillment_places(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_service.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_remove_fulfillment_places_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 = ProductServiceClient( + 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_fulfillment_places), + '__call__') as call: + client.remove_fulfillment_places() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveFulfillmentPlacesRequest() + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveFulfillmentPlacesRequest): + client = ProductServiceAsyncClient( + 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_fulfillment_places), + '__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.remove_fulfillment_places(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveFulfillmentPlacesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_async_from_dict(): + await test_remove_fulfillment_places_async(request_type=dict) + + +def test_remove_fulfillment_places_field_headers(): + client = ProductServiceClient( + 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_service.RemoveFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.remove_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.RemoveFulfillmentPlacesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.remove_fulfillment_places(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=product_value', + ) in kw['metadata'] + + +def test_remove_fulfillment_places_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__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.remove_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_fulfillment_places_flattened_error(): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_fulfillment_places), + '__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.remove_fulfillment_places( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_fulfillment_places_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddLocalInventoriesRequest, + dict, +]) +def test_add_local_inventories(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.add_local_inventories(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_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_add_local_inventories_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 = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + client.add_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + +@pytest.mark.asyncio +async def test_add_local_inventories_async(transport: str = 'grpc_asyncio', request_type=product_service.AddLocalInventoriesRequest): + client = ProductServiceAsyncClient( + 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_local_inventories), + '__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.add_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.AddLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_add_local_inventories_async_from_dict(): + await test_add_local_inventories_async(request_type=dict) + + +def test_add_local_inventories_field_headers(): + client = ProductServiceClient( + 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_service.AddLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.add_local_inventories(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.AddLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.add_local_inventories(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=product_value', + ) in kw['metadata'] + + +def test_add_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__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.add_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_add_local_inventories_flattened_error(): + client = ProductServiceClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_local_inventories), + '__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.add_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveLocalInventoriesRequest, + dict, +]) +def test_remove_local_inventories(request_type, transport: str = 'grpc'): + client = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.remove_local_inventories(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_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_remove_local_inventories_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 = ProductServiceClient( + 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_local_inventories), + '__call__') as call: + client.remove_local_inventories() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + +@pytest.mark.asyncio +async def test_remove_local_inventories_async(transport: str = 'grpc_asyncio', request_type=product_service.RemoveLocalInventoriesRequest): + client = ProductServiceAsyncClient( + 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_local_inventories), + '__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.remove_local_inventories(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == product_service.RemoveLocalInventoriesRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_remove_local_inventories_async_from_dict(): + await test_remove_local_inventories_async(request_type=dict) + + +def test_remove_local_inventories_field_headers(): + client = ProductServiceClient( + 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_service.RemoveLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.remove_local_inventories(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=product_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_local_inventories_field_headers_async(): + client = ProductServiceAsyncClient( + 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_service.RemoveLocalInventoriesRequest() + + request.product = 'product_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.remove_local_inventories(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=product_value', + ) in kw['metadata'] + + +def test_remove_local_inventories_flattened(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__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.remove_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + + +def test_remove_local_inventories_flattened_error(): + client = ProductServiceClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_local_inventories), + '__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.remove_local_inventories( + 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].product + mock_val = 'product_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_local_inventories_flattened_error_async(): + client = ProductServiceAsyncClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.CreateProductRequest, + dict, +]) +def test_create_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_create_product_rest_required_fields(request_type=product_service.CreateProductRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["product_id"] = "" + 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 + assert "productId" not in jsonified_request + + 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 + assert "productId" in jsonified_request + assert jsonified_request["productId"] == request_init["product_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["productId"] = 'product_id_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' + assert "productId" in jsonified_request + assert jsonified_request["productId"] == 'product_id_value' + + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_product.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 + + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_product(request) + + expected_params = [ + ( + "productId", + "", + ), + ('$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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("productId", )) & set(("parent", "product", "productId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_product_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_create_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_create_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.CreateProductRequest.pb(product_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 = gcr_product.Product.to_json(gcr_product.Product()) + + request = product_service.CreateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_product.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_service.CreateProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = ProductServiceClient( + 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 = gcr_product.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2beta/{parent=projects/*/locations/*/catalogs/*/branches/*}/products" % client.transport._host, args[1]) + + +def test_create_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.CreateProductRequest(), + parent='parent_value', + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + product_id='product_id_value', + ) + + +def test_create_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.GetProductRequest, + dict, +]) +def test_get_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.Product( + name='name_value', + id='id_value', + type_=product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_get_product_rest_required_fields(request_type=product_service.GetProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product.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 + + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(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.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_get_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_get_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.GetProductRequest.pb(product_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.Product.to_json(product.Product()) + + request = product_service.GetProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product.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_service.GetProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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 = ProductServiceClient( + 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.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # 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 + pb_return_value = product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_get_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.GetProductRequest(), + name='name_value', + ) + + +def test_get_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.ListProductsRequest, + dict, +]) +def test_list_products_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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_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 + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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_service.ListProductsRequest): + transport_class = transports.ProductServiceRestTransport + + 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(("filter", "page_size", "page_token", "read_mask", )) + 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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = product_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 + + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(("filter", "pageSize", "pageToken", "readMask", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_products_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_list_products") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_list_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.ListProductsRequest.pb(product_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_service.ListProductsResponse.to_json(product_service.ListProductsResponse()) + + request = product_service.ListProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = product_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_service.ListProductsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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.list_products(request) + + +def test_list_products_rest_flattened(): + client = ProductServiceClient( + 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_service.ListProductsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4'} + + # 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 + pb_return_value = product_service.ListProductsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2beta/{parent=projects/*/locations/*/catalogs/*/branches/*}/products" % client.transport._host, args[1]) + + +def test_list_products_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.ListProductsRequest(), + parent='parent_value', + ) + + +def test_list_products_rest_pager(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + product.Product(), + ], + next_page_token='abc', + ), + product_service.ListProductsResponse( + products=[], + next_page_token='def', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + ], + next_page_token='ghi', + ), + product_service.ListProductsResponse( + products=[ + product.Product(), + product.Product(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(product_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/catalogs/sample3/branches/sample4'} + + pager = client.list_products(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, product.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_service.UpdateProductRequest, + dict, +]) +def test_update_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = gcr_product.Product( + name='name_value', + id='id_value', + type_=gcr_product.Product.Type.PRIMARY, + primary_product_id='primary_product_id_value', + collection_member_ids=['collection_member_ids_value'], + gtin='gtin_value', + categories=['categories_value'], + title='title_value', + brands=['brands_value'], + description='description_value', + language_code='language_code_value', + tags=['tags_value'], + availability=gcr_product.Product.Availability.IN_STOCK, + uri='uri_value', + sizes=['sizes_value'], + materials=['materials_value'], + patterns=['patterns_value'], + conditions=['conditions_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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, gcr_product.Product) + assert response.name == 'name_value' + assert response.id == 'id_value' + assert response.type_ == gcr_product.Product.Type.PRIMARY + assert response.primary_product_id == 'primary_product_id_value' + assert response.collection_member_ids == ['collection_member_ids_value'] + assert response.gtin == 'gtin_value' + assert response.categories == ['categories_value'] + assert response.title == 'title_value' + assert response.brands == ['brands_value'] + assert response.description == 'description_value' + assert response.language_code == 'language_code_value' + assert response.tags == ['tags_value'] + assert response.availability == gcr_product.Product.Availability.IN_STOCK + assert response.uri == 'uri_value' + assert response.sizes == ['sizes_value'] + assert response.materials == ['materials_value'] + assert response.patterns == ['patterns_value'] + assert response.conditions == ['conditions_value'] + + +def test_update_product_rest_required_fields(request_type=product_service.UpdateProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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(("allow_missing", "update_mask", )) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_product.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 + + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_product._get_unset_required_fields({}) + assert set(unset_fields) == (set(("allowMissing", "updateMask", )) & set(("product", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_product_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_update_product") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_update_product") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.UpdateProductRequest.pb(product_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 = gcr_product.Product.to_json(gcr_product.Product()) + + request = product_service.UpdateProductRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_product.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_service.UpdateProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + request_init["product"] = {'expire_time': {'seconds': 751, 'nanos': 543}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]} + 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 = ProductServiceClient( + 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 = gcr_product.Product() + + # get arguments that satisfy an http rule for this method + sample_request = {'product': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + + # get truthy value for each flattened field + mock_args = dict( + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + 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 + pb_return_value = gcr_product.Product.pb(return_value) + json_return_value = json_format.MessageToJson(pb_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/v2beta/{product.name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_update_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.UpdateProductRequest(), + product=gcr_product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.DeleteProductRequest, + dict, +]) +def test_delete_product_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_service.DeleteProductRequest): + transport_class = transports.ProductServiceRestTransport + + 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 = ProductServiceClient( + 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.ProductServiceRestTransport(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.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "pre_delete_product") as pre: + pre.assert_not_called() + pb_message = product_service.DeleteProductRequest.pb(product_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_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_service.DeleteProductRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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 = ProductServiceClient( + 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/catalogs/sample3/branches/sample4/products/sample5'} + + # 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/v2beta/{name=projects/*/locations/*/catalogs/*/branches/*/products/**}" % client.transport._host, args[1]) + + +def test_delete_product_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_service.DeleteProductRequest(), + name='name_value', + ) + + +def test_delete_product_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportProductsRequest, + dict, +]) +def test_import_products_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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 = 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_products(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_products_rest_required_fields(request_type=import_config.ImportProductsRequest): + transport_class = transports.ProductServiceRestTransport + + 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_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()).import_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 = ProductServiceClient( + 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_products(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_products_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_products._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_products_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_import_products") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_import_products") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportProductsRequest.pb(import_config.ImportProductsRequest()) + 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 = import_config.ImportProductsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_products(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_products_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportProductsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3/branches/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.import_products(request) + + +def test_import_products_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.SetInventoryRequest, + dict, +]) +def test_set_inventory_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + 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.set_inventory(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_set_inventory_rest_required_fields(request_type=product_service.SetInventoryRequest): + transport_class = transports.ProductServiceRestTransport + + 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()).set_inventory._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()).set_inventory._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + + client = ProductServiceClient( + 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.set_inventory(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_set_inventory_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.set_inventory._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("inventory", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_set_inventory_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_set_inventory") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_set_inventory") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.SetInventoryRequest.pb(product_service.SetInventoryRequest()) + 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_service.SetInventoryRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.set_inventory(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_set_inventory_rest_bad_request(transport: str = 'rest', request_type=product_service.SetInventoryRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + 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.set_inventory(request) + + +def test_set_inventory_rest_flattened(): + client = ProductServiceClient( + 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 = {'inventory': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'}} + + # get truthy value for each flattened field + mock_args = dict( + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_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 + json_return_value = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.set_inventory(**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/v2beta/{inventory.name=projects/*/locations/*/catalogs/*/branches/*/products/**}:setInventory" % client.transport._host, args[1]) + + +def test_set_inventory_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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.set_inventory( + product_service.SetInventoryRequest(), + inventory=product.Product(expire_time=timestamp_pb2.Timestamp(seconds=751)), + set_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_set_inventory_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddFulfillmentPlacesRequest, + dict, +]) +def test_add_fulfillment_places_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.add_fulfillment_places(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_add_fulfillment_places_rest_required_fields(request_type=product_service.AddFulfillmentPlacesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["type_"] = "" + request_init["place_ids"] = "" + 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_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["type"] = 'type__value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "type" in jsonified_request + assert jsonified_request["type"] == 'type__value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.add_fulfillment_places(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_fulfillment_places_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_fulfillment_places._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "type", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_fulfillment_places_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_add_fulfillment_places") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_add_fulfillment_places") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.AddFulfillmentPlacesRequest.pb(product_service.AddFulfillmentPlacesRequest()) + 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_service.AddFulfillmentPlacesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.add_fulfillment_places(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_fulfillment_places_rest_bad_request(transport: str = 'rest', request_type=product_service.AddFulfillmentPlacesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_fulfillment_places(request) + + +def test_add_fulfillment_places_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_fulfillment_places(**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/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addFulfillmentPlaces" % client.transport._host, args[1]) + + +def test_add_fulfillment_places_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.AddFulfillmentPlacesRequest(), + product='product_value', + ) + + +def test_add_fulfillment_places_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveFulfillmentPlacesRequest, + dict, +]) +def test_remove_fulfillment_places_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.remove_fulfillment_places(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_remove_fulfillment_places_rest_required_fields(request_type=product_service.RemoveFulfillmentPlacesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["type_"] = "" + request_init["place_ids"] = "" + 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_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["type"] = 'type__value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_fulfillment_places._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "type" in jsonified_request + assert jsonified_request["type"] == 'type__value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.remove_fulfillment_places(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_fulfillment_places_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_fulfillment_places._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "type", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_fulfillment_places_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_remove_fulfillment_places") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_remove_fulfillment_places") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.RemoveFulfillmentPlacesRequest.pb(product_service.RemoveFulfillmentPlacesRequest()) + 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_service.RemoveFulfillmentPlacesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.remove_fulfillment_places(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_fulfillment_places_rest_bad_request(transport: str = 'rest', request_type=product_service.RemoveFulfillmentPlacesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_fulfillment_places(request) + + +def test_remove_fulfillment_places_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_fulfillment_places(**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/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeFulfillmentPlaces" % client.transport._host, args[1]) + + +def test_remove_fulfillment_places_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_fulfillment_places( + product_service.RemoveFulfillmentPlacesRequest(), + product='product_value', + ) + + +def test_remove_fulfillment_places_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.AddLocalInventoriesRequest, + dict, +]) +def test_add_local_inventories_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.add_local_inventories(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_add_local_inventories_rest_required_fields(request_type=product_service.AddLocalInventoriesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + 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_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + + client = ProductServiceClient( + 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.add_local_inventories(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_local_inventories_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_local_inventories._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "localInventories", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_local_inventories_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_add_local_inventories") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_add_local_inventories") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.AddLocalInventoriesRequest.pb(product_service.AddLocalInventoriesRequest()) + 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_service.AddLocalInventoriesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.add_local_inventories(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_local_inventories_rest_bad_request(transport: str = 'rest', request_type=product_service.AddLocalInventoriesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_local_inventories(request) + + +def test_add_local_inventories_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_local_inventories(**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/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:addLocalInventories" % client.transport._host, args[1]) + + +def test_add_local_inventories_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_local_inventories( + product_service.AddLocalInventoriesRequest(), + product='product_value', + ) + + +def test_add_local_inventories_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + product_service.RemoveLocalInventoriesRequest, + dict, +]) +def test_remove_local_inventories_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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.remove_local_inventories(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_remove_local_inventories_rest_required_fields(request_type=product_service.RemoveLocalInventoriesRequest): + transport_class = transports.ProductServiceRestTransport + + request_init = {} + request_init["product"] = "" + request_init["place_ids"] = "" + 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_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["product"] = 'product_value' + jsonified_request["placeIds"] = 'place_ids_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_local_inventories._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "product" in jsonified_request + assert jsonified_request["product"] == 'product_value' + assert "placeIds" in jsonified_request + assert jsonified_request["placeIds"] == 'place_ids_value' + + client = ProductServiceClient( + 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.remove_local_inventories(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_local_inventories_rest_unset_required_fields(): + transport = transports.ProductServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_local_inventories._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("product", "placeIds", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_local_inventories_rest_interceptors(null_interceptor): + transport = transports.ProductServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ProductServiceRestInterceptor(), + ) + client = ProductServiceClient(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.ProductServiceRestInterceptor, "post_remove_local_inventories") as post, \ + mock.patch.object(transports.ProductServiceRestInterceptor, "pre_remove_local_inventories") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = product_service.RemoveLocalInventoriesRequest.pb(product_service.RemoveLocalInventoriesRequest()) + 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_service.RemoveLocalInventoriesRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.remove_local_inventories(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_local_inventories_rest_bad_request(transport: str = 'rest', request_type=product_service.RemoveLocalInventoriesRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + 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_local_inventories(request) + + +def test_remove_local_inventories_rest_flattened(): + client = ProductServiceClient( + 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 = {'product': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/products/sample5'} + + # get truthy value for each flattened field + mock_args = dict( + 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 = json_format.MessageToJson(return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_local_inventories(**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/v2beta/{product=projects/*/locations/*/catalogs/*/branches/*/products/**}:removeLocalInventories" % client.transport._host, args[1]) + + +def test_remove_local_inventories_rest_flattened_error(transport: str = 'rest'): + client = ProductServiceClient( + 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_local_inventories( + product_service.RemoveLocalInventoriesRequest(), + product='product_value', + ) + + +def test_remove_local_inventories_rest_error(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ProductServiceClient( + 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 = ProductServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ProductServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ProductServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ProductServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ProductServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + transports.ProductServiceRestTransport, +]) +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 = ProductServiceClient.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 = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ProductServiceGrpcTransport, + ) + +def test_product_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_product_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.product_service.transports.ProductServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ProductServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_product', + 'get_product', + 'list_products', + 'update_product', + 'delete_product', + 'import_products', + 'set_inventory', + 'add_fulfillment_places', + 'remove_fulfillment_places', + 'add_local_inventories', + 'remove_local_inventories', + 'get_operation', + 'list_operations', + ) + 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_service_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.retail_v2beta.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_product_service_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.retail_v2beta.services.product_service.transports.ProductServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ProductServiceTransport() + adc.assert_called_once() + + +def test_product_service_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) + ProductServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + ], +) +def test_product_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ProductServiceGrpcTransport, + transports.ProductServiceGrpcAsyncIOTransport, + transports.ProductServiceRestTransport, + ], +) +def test_product_service_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.ProductServiceGrpcTransport, grpc_helpers), + (transports.ProductServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_product_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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_service_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.ProductServiceRestTransport ( + 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_service_rest_lro_client(): + client = ProductServiceClient( + 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_service_host_no_port(transport_name): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_product_service_host_with_port(transport_name): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_product_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ProductServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ProductServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_product._session + session2 = client2.transport.create_product._session + assert session1 != session2 + session1 = client1.transport.get_product._session + session2 = client2.transport.get_product._session + assert session1 != session2 + session1 = client1.transport.list_products._session + session2 = client2.transport.list_products._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.import_products._session + session2 = client2.transport.import_products._session + assert session1 != session2 + session1 = client1.transport.set_inventory._session + session2 = client2.transport.set_inventory._session + assert session1 != session2 + session1 = client1.transport.add_fulfillment_places._session + session2 = client2.transport.add_fulfillment_places._session + assert session1 != session2 + session1 = client1.transport.remove_fulfillment_places._session + session2 = client2.transport.remove_fulfillment_places._session + assert session1 != session2 + session1 = client1.transport.add_local_inventories._session + session2 = client2.transport.add_local_inventories._session + assert session1 != session2 + session1 = client1.transport.remove_local_inventories._session + session2 = client2.transport.remove_local_inventories._session + assert session1 != session2 +def test_product_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcTransport( + 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_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ProductServiceGrpcAsyncIOTransport( + 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.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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.ProductServiceGrpcTransport, transports.ProductServiceGrpcAsyncIOTransport]) +def test_product_service_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_service_grpc_lro_client(): + client = ProductServiceClient( + 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_service_grpc_lro_async_client(): + client = ProductServiceAsyncClient( + 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_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = ProductServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = ProductServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_branch_path(path) + assert expected == actual + +def test_product_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + branch = "abalone" + product = "squid" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = ProductServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "clam", + "location": "whelk", + "catalog": "octopus", + "branch": "oyster", + "product": "nudibranch", + } + path = ProductServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "cuttlefish" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ProductServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "mussel", + } + path = ProductServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "winkle" + expected = "folders/{folder}".format(folder=folder, ) + actual = ProductServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nautilus", + } + path = ProductServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "scallop" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ProductServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "abalone", + } + path = ProductServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "squid" + expected = "projects/{project}".format(project=project, ) + actual = ProductServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "clam", + } + path = ProductServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "whelk" + location = "octopus" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ProductServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + } + path = ProductServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ProductServiceClient.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.ProductServiceTransport, '_prep_wrapped_messages') as prep: + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ProductServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ProductServiceClient.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 = ProductServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ProductServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ProductServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ProductServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ProductServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ProductServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ProductServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ProductServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ProductServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ProductServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ProductServiceClient( + 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 = ProductServiceClient( + 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", [ + (ProductServiceClient, transports.ProductServiceGrpcTransport), + (ProductServiceAsyncClient, transports.ProductServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_search_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_search_service.py new file mode 100644 index 00000000..8d73e194 --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_search_service.py @@ -0,0 +1,2263 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.search_service import SearchServiceAsyncClient +from google.cloud.retail_v2beta.services.search_service import SearchServiceClient +from google.cloud.retail_v2beta.services.search_service import pagers +from google.cloud.retail_v2beta.services.search_service import transports +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import search_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +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 SearchServiceClient._get_default_mtls_endpoint(None) is None + assert SearchServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert SearchServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (SearchServiceClient, "grpc"), + (SearchServiceAsyncClient, "grpc_asyncio"), + (SearchServiceClient, "rest"), +]) +def test_search_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.SearchServiceGrpcTransport, "grpc"), + (transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.SearchServiceRestTransport, "rest"), +]) +def test_search_service_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", [ + (SearchServiceClient, "grpc"), + (SearchServiceAsyncClient, "grpc_asyncio"), + (SearchServiceClient, "rest"), +]) +def test_search_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_search_service_client_get_transport_class(): + transport = SearchServiceClient.get_transport_class() + available_transports = [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceRestTransport, + ] + assert transport in available_transports + + transport = SearchServiceClient.get_transport_class("grpc") + assert transport == transports.SearchServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_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(SearchServiceClient, '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(SearchServiceClient, '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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "true"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", "false"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", "true"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_search_service_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", [ + SearchServiceClient, SearchServiceAsyncClient +]) +@mock.patch.object(SearchServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceClient)) +@mock.patch.object(SearchServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(SearchServiceAsyncClient)) +def test_search_service_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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc"), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest"), +]) +def test_search_service_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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", grpc_helpers), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (SearchServiceClient, transports.SearchServiceRestTransport, "rest", None), +]) +def test_search_service_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_search_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.search_service.transports.SearchServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = SearchServiceClient( + 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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport, "grpc", grpc_helpers), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_search_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + search_service.SearchRequest, + dict, +]) +def test_search(request_type, transport: str = 'grpc'): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + ) + response = client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +def test_search_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 = SearchServiceClient( + 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.search), + '__call__') as call: + client.search() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + +@pytest.mark.asyncio +async def test_search_async(transport: str = 'grpc_asyncio', request_type=search_service.SearchRequest): + client = SearchServiceAsyncClient( + 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.search), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + )) + response = await client.search(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == search_service.SearchRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchAsyncPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +@pytest.mark.asyncio +async def test_search_async_from_dict(): + await test_search_async(request_type=dict) + + +def test_search_field_headers(): + client = SearchServiceClient( + 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 = search_service.SearchRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = search_service.SearchResponse() + client.search(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', + 'placement=placement_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_search_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = search_service.SearchRequest() + + request.placement = 'placement_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(search_service.SearchResponse()) + await client.search(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', + 'placement=placement_value', + ) in kw['metadata'] + + +def test_search_pager(transport_name: str = "grpc"): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('placement', ''), + )), + ) + pager = client.search(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in results) +def test_search_pages(transport_name: str = "grpc"): + client = SearchServiceClient( + 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.search), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + pages = list(client.search(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_search_async_pager(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + RuntimeError, + ) + async_pager = await client.search(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, search_service.SearchResponse.SearchResult) + for i in responses) + + +@pytest.mark.asyncio +async def test_search_async_pages(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.search), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + 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.search(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", [ + search_service.SearchRequest, + dict, +]) +def test_search_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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 = search_service.SearchResponse( + total_size=1086, + corrected_query='corrected_query_value', + attribution_token='attribution_token_value', + next_page_token='next_page_token_value', + redirect_uri='redirect_uri_value', + applied_controls=['applied_controls_value'], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = search_service.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.search(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.SearchPager) + assert response.total_size == 1086 + assert response.corrected_query == 'corrected_query_value' + assert response.attribution_token == 'attribution_token_value' + assert response.next_page_token == 'next_page_token_value' + assert response.redirect_uri == 'redirect_uri_value' + assert response.applied_controls == ['applied_controls_value'] + + +def test_search_rest_required_fields(request_type=search_service.SearchRequest): + transport_class = transports.SearchServiceRestTransport + + request_init = {} + request_init["placement"] = "" + request_init["visitor_id"] = "" + 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()).search._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["placement"] = 'placement_value' + jsonified_request["visitorId"] = 'visitor_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).search._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "placement" in jsonified_request + assert jsonified_request["placement"] == 'placement_value' + assert "visitorId" in jsonified_request + assert jsonified_request["visitorId"] == 'visitor_id_value' + + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = search_service.SearchResponse() + # 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 + + pb_return_value = search_service.SearchResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.search(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_search_rest_unset_required_fields(): + transport = transports.SearchServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.search._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("placement", "visitorId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_search_rest_interceptors(null_interceptor): + transport = transports.SearchServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.SearchServiceRestInterceptor(), + ) + client = SearchServiceClient(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.SearchServiceRestInterceptor, "post_search") as post, \ + mock.patch.object(transports.SearchServiceRestInterceptor, "pre_search") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = search_service.SearchRequest.pb(search_service.SearchRequest()) + 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 = search_service.SearchResponse.to_json(search_service.SearchResponse()) + + request = search_service.SearchRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = search_service.SearchResponse() + + client.search(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_search_rest_bad_request(transport: str = 'rest', request_type=search_service.SearchRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/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.search(request) + + +def test_search_rest_pager(transport: str = 'rest'): + client = SearchServiceClient( + 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 = ( + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + next_page_token='abc', + ), + search_service.SearchResponse( + results=[], + next_page_token='def', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + ], + next_page_token='ghi', + ), + search_service.SearchResponse( + results=[ + search_service.SearchResponse.SearchResult(), + search_service.SearchResponse.SearchResult(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(search_service.SearchResponse.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 = {'placement': 'projects/sample1/locations/sample2/catalogs/sample3/placements/sample4'} + + pager = client.search(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, search_service.SearchResponse.SearchResult) + for i in results) + + pages = list(client.search(request=sample_request).pages) + for page_, token in zip(pages, ['abc','def','ghi', '']): + assert page_.raw_page.next_page_token == token + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = SearchServiceClient( + 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 = SearchServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = SearchServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = SearchServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.SearchServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.SearchServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + transports.SearchServiceRestTransport, +]) +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 = SearchServiceClient.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 = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.SearchServiceGrpcTransport, + ) + +def test_search_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_search_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.search_service.transports.SearchServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.SearchServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'search', + 'get_operation', + 'list_operations', + ) + 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_search_service_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.retail_v2beta.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_search_service_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.retail_v2beta.services.search_service.transports.SearchServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.SearchServiceTransport() + adc.assert_called_once() + + +def test_search_service_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) + SearchServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + ], +) +def test_search_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.SearchServiceGrpcTransport, + transports.SearchServiceGrpcAsyncIOTransport, + transports.SearchServiceRestTransport, + ], +) +def test_search_service_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.SearchServiceGrpcTransport, grpc_helpers), + (transports.SearchServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_search_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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_search_service_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.SearchServiceRestTransport ( + 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_search_service_host_no_port(transport_name): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_search_service_host_with_port(transport_name): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_search_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = SearchServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = SearchServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.search._session + session2 = client2.transport.search._session + assert session1 != session2 +def test_search_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcTransport( + 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_search_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.SearchServiceGrpcAsyncIOTransport( + 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.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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.SearchServiceGrpcTransport, transports.SearchServiceGrpcAsyncIOTransport]) +def test_search_service_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_branch_path(): + project = "squid" + location = "clam" + catalog = "whelk" + branch = "octopus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}".format(project=project, location=location, catalog=catalog, branch=branch, ) + actual = SearchServiceClient.branch_path(project, location, catalog, branch) + assert expected == actual + + +def test_parse_branch_path(): + expected = { + "project": "oyster", + "location": "nudibranch", + "catalog": "cuttlefish", + "branch": "mussel", + } + path = SearchServiceClient.branch_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_branch_path(path) + assert expected == actual + +def test_experiment_path(): + project = "winkle" + location = "nautilus" + catalog = "scallop" + experiment = "abalone" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/experiments/{experiment}".format(project=project, location=location, catalog=catalog, experiment=experiment, ) + actual = SearchServiceClient.experiment_path(project, location, catalog, experiment) + assert expected == actual + + +def test_parse_experiment_path(): + expected = { + "project": "squid", + "location": "clam", + "catalog": "whelk", + "experiment": "octopus", + } + path = SearchServiceClient.experiment_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_experiment_path(path) + assert expected == actual + +def test_product_path(): + project = "oyster" + location = "nudibranch" + catalog = "cuttlefish" + branch = "mussel" + product = "winkle" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = SearchServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "nautilus", + "location": "scallop", + "catalog": "abalone", + "branch": "squid", + "product": "clam", + } + path = SearchServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_product_path(path) + assert expected == actual + +def test_serving_config_path(): + project = "whelk" + location = "octopus" + catalog = "oyster" + serving_config = "nudibranch" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + actual = SearchServiceClient.serving_config_path(project, location, catalog, serving_config) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "cuttlefish", + "location": "mussel", + "catalog": "winkle", + "serving_config": "nautilus", + } + path = SearchServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_serving_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "scallop" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = SearchServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "abalone", + } + path = SearchServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "squid" + expected = "folders/{folder}".format(folder=folder, ) + actual = SearchServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "clam", + } + path = SearchServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "whelk" + expected = "organizations/{organization}".format(organization=organization, ) + actual = SearchServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "octopus", + } + path = SearchServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "oyster" + expected = "projects/{project}".format(project=project, ) + actual = SearchServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nudibranch", + } + path = SearchServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "cuttlefish" + location = "mussel" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = SearchServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "winkle", + "location": "nautilus", + } + path = SearchServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = SearchServiceClient.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.SearchServiceTransport, '_prep_wrapped_messages') as prep: + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.SearchServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = SearchServiceClient.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 = SearchServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = SearchServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = SearchServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = SearchServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = SearchServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = SearchServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = SearchServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = SearchServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = SearchServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = SearchServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = SearchServiceClient( + 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 = SearchServiceClient( + 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", [ + (SearchServiceClient, transports.SearchServiceGrpcTransport), + (SearchServiceAsyncClient, transports.SearchServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_serving_config_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_serving_config_service.py new file mode 100644 index 00000000..7a0b476a --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_serving_config_service.py @@ -0,0 +1,5655 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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.location import locations_pb2 +from google.cloud.retail_v2beta.services.serving_config_service import ServingConfigServiceAsyncClient +from google.cloud.retail_v2beta.services.serving_config_service import ServingConfigServiceClient +from google.cloud.retail_v2beta.services.serving_config_service import pagers +from google.cloud.retail_v2beta.services.serving_config_service import transports +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import search_service +from google.cloud.retail_v2beta.types import serving_config +from google.cloud.retail_v2beta.types import serving_config as gcr_serving_config +from google.cloud.retail_v2beta.types import serving_config_service +from google.longrunning import operations_pb2 # type: ignore +from google.oauth2 import service_account +from google.protobuf import field_mask_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 ServingConfigServiceClient._get_default_mtls_endpoint(None) is None + assert ServingConfigServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert ServingConfigServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (ServingConfigServiceClient, "grpc"), + (ServingConfigServiceAsyncClient, "grpc_asyncio"), + (ServingConfigServiceClient, "rest"), +]) +def test_serving_config_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.ServingConfigServiceGrpcTransport, "grpc"), + (transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.ServingConfigServiceRestTransport, "rest"), +]) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, "grpc"), + (ServingConfigServiceAsyncClient, "grpc_asyncio"), + (ServingConfigServiceClient, "rest"), +]) +def test_serving_config_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_serving_config_service_client_get_transport_class(): + transport = ServingConfigServiceClient.get_transport_class() + available_transports = [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceRestTransport, + ] + assert transport in available_transports + + transport = ServingConfigServiceClient.get_transport_class("grpc") + assert transport == transports.ServingConfigServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest"), +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +def test_serving_config_service_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(ServingConfigServiceClient, '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(ServingConfigServiceClient, '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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", "true"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", "false"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", "true"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_serving_config_service_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", [ + ServingConfigServiceClient, ServingConfigServiceAsyncClient +]) +@mock.patch.object(ServingConfigServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceClient)) +@mock.patch.object(ServingConfigServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(ServingConfigServiceAsyncClient)) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc"), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest"), +]) +def test_serving_config_service_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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", grpc_helpers), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (ServingConfigServiceClient, transports.ServingConfigServiceRestTransport, "rest", None), +]) +def test_serving_config_service_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_serving_config_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.serving_config_service.transports.ServingConfigServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = ServingConfigServiceClient( + 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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport, "grpc", grpc_helpers), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_serving_config_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.CreateServingConfigRequest, + dict, +]) +def test_create_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.create_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_create_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.create_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + +@pytest.mark.asyncio +async def test_create_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.CreateServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.create_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.CreateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_create_serving_config_async_from_dict(): + await test_create_serving_config_async(request_type=dict) + + +def test_create_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.CreateServingConfigRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.create_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.CreateServingConfigRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.create_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.create_serving_config( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_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].serving_config + mock_val = gcr_serving_config.ServingConfig(name='name_value') + assert arg == mock_val + arg = args[0].serving_config_id + mock_val = 'serving_config_id_value' + assert arg == mock_val + + +def test_create_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + +@pytest.mark.asyncio +async def test_create_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.create_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.create_serving_config( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_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].serving_config + mock_val = gcr_serving_config.ServingConfig(name='name_value') + assert arg == mock_val + arg = args[0].serving_config_id + mock_val = 'serving_config_id_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_create_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.DeleteServingConfigRequest, + dict, +]) +def test_delete_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = None + response = client.delete_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.delete_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + +@pytest.mark.asyncio +async def test_delete_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.DeleteServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + response = await client.delete_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.DeleteServingConfigRequest() + + # Establish that the response is the type that we expect. + assert response is None + + +@pytest.mark.asyncio +async def test_delete_serving_config_async_from_dict(): + await test_delete_serving_config_async(request_type=dict) + + +def test_delete_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.DeleteServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__call__') as call: + call.return_value = None + client.delete_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.DeleteServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(None) + await client.delete_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__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_serving_config( + 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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_delete_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.delete_serving_config), + '__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_serving_config( + 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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.UpdateServingConfigRequest, + dict, +]) +def test_update_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.update_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_update_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.update_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + +@pytest.mark.asyncio +async def test_update_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.UpdateServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.update_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.UpdateServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_update_serving_config_async_from_dict(): + await test_update_serving_config_async(request_type=dict) + + +def test_update_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.UpdateServingConfigRequest() + + request.serving_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.update_serving_config(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', + 'serving_config.name=name_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_update_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.UpdateServingConfigRequest() + + request.serving_config.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.update_serving_config(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', + 'serving_config.name=name_value', + ) in kw['metadata'] + + +def test_update_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.update_serving_config( + serving_config=gcr_serving_config.ServingConfig(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].serving_config + mock_val = gcr_serving_config.ServingConfig(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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + +@pytest.mark.asyncio +async def test_update_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.update_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.update_serving_config( + serving_config=gcr_serving_config.ServingConfig(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].serving_config + mock_val = gcr_serving_config.ServingConfig(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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.GetServingConfigRequest, + dict, +]) +def test_get_serving_config(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.get_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_get_serving_config_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 = ServingConfigServiceClient( + 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_serving_config), + '__call__') as call: + client.get_serving_config() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + +@pytest.mark.asyncio +async def test_get_serving_config_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.GetServingConfigRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.get_serving_config(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.GetServingConfigRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_get_serving_config_async_from_dict(): + await test_get_serving_config_async(request_type=dict) + + +def test_get_serving_config_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.GetServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + call.return_value = serving_config.ServingConfig() + client.get_serving_config(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_serving_config_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.GetServingConfigRequest() + + request.name = 'name_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig()) + await client.get_serving_config(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_serving_config_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.get_serving_config( + 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_serving_config_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + +@pytest.mark.asyncio +async def test_get_serving_config_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.get_serving_config), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.get_serving_config( + 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_serving_config_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.ListServingConfigsRequest, + dict, +]) +def test_list_serving_configs(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + ) + response = client.list_serving_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_serving_configs_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 = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + client.list_serving_configs() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + +@pytest.mark.asyncio +async def test_list_serving_configs_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.ListServingConfigsRequest): + client = ServingConfigServiceAsyncClient( + 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_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + )) + response = await client.list_serving_configs(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.ListServingConfigsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsAsyncPager) + assert response.next_page_token == 'next_page_token_value' + + +@pytest.mark.asyncio +async def test_list_serving_configs_async_from_dict(): + await test_list_serving_configs_async(request_type=dict) + + +def test_list_serving_configs_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.ListServingConfigsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + call.return_value = serving_config_service.ListServingConfigsResponse() + client.list_serving_configs(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_serving_configs_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.ListServingConfigsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse()) + await client.list_serving_configs(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_serving_configs_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.list_serving_configs( + 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_serving_configs_flattened_error(): + client = ServingConfigServiceClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + +@pytest.mark.asyncio +async def test_list_serving_configs_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = serving_config_service.ListServingConfigsResponse() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(serving_config_service.ListServingConfigsResponse()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.list_serving_configs( + 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_serving_configs_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + + +def test_list_serving_configs_pager(transport_name: str = "grpc"): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + + metadata = () + metadata = tuple(metadata) + ( + gapic_v1.routing_header.to_grpc_metadata(( + ('parent', ''), + )), + ) + pager = client.list_serving_configs(request={}) + + assert pager._metadata == metadata + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, serving_config.ServingConfig) + for i in results) +def test_list_serving_configs_pages(transport_name: str = "grpc"): + client = ServingConfigServiceClient( + 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_serving_configs), + '__call__') as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + pages = list(client.list_serving_configs(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_serving_configs_async_pager(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + RuntimeError, + ) + async_pager = await client.list_serving_configs(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, serving_config.ServingConfig) + for i in responses) + + +@pytest.mark.asyncio +async def test_list_serving_configs_async_pages(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials, + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.list_serving_configs), + '__call__', new_callable=mock.AsyncMock) as call: + # Set the response to a series of pages. + call.side_effect = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + 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_serving_configs(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", [ + serving_config_service.AddControlRequest, + dict, +]) +def test_add_control(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.add_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_add_control_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 = ServingConfigServiceClient( + 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_control), + '__call__') as call: + client.add_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + +@pytest.mark.asyncio +async def test_add_control_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.AddControlRequest): + client = ServingConfigServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.add_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.AddControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_add_control_async_from_dict(): + await test_add_control_async(request_type=dict) + + +def test_add_control_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.AddControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.add_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_add_control_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.AddControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.add_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +def test_add_control_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.add_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + + +def test_add_control_flattened_error(): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + +@pytest.mark.asyncio +async def test_add_control_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.add_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.add_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_add_control_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.RemoveControlRequest, + dict, +]) +def test_remove_control(request_type, transport: str = 'grpc'): + client = ServingConfigServiceClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + response = client.remove_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_remove_control_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 = ServingConfigServiceClient( + 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_control), + '__call__') as call: + client.remove_control() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + +@pytest.mark.asyncio +async def test_remove_control_async(transport: str = 'grpc_asyncio', request_type=serving_config_service.RemoveControlRequest): + client = ServingConfigServiceAsyncClient( + 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_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + )) + response = await client.remove_control(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == serving_config_service.RemoveControlRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +@pytest.mark.asyncio +async def test_remove_control_async_from_dict(): + await test_remove_control_async(request_type=dict) + + +def test_remove_control_field_headers(): + client = ServingConfigServiceClient( + 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 = serving_config_service.RemoveControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + call.return_value = gcr_serving_config.ServingConfig() + client.remove_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +@pytest.mark.asyncio +async def test_remove_control_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = serving_config_service.RemoveControlRequest() + + request.serving_config = 'serving_config_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + await client.remove_control(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', + 'serving_config=serving_config_value', + ) in kw['metadata'] + + +def test_remove_control_flattened(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + client.remove_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + + +def test_remove_control_flattened_error(): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + +@pytest.mark.asyncio +async def test_remove_control_flattened_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.remove_control), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = gcr_serving_config.ServingConfig() + + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(gcr_serving_config.ServingConfig()) + # Call the method with a truthy value for each flattened field, + # using the keyword arguments to the method. + response = await client.remove_control( + serving_config='serving_config_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].serving_config + mock_val = 'serving_config_value' + assert arg == mock_val + +@pytest.mark.asyncio +async def test_remove_control_flattened_error_async(): + client = ServingConfigServiceAsyncClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.CreateServingConfigRequest, + dict, +]) +def test_create_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["serving_config"] = {'name': 'name_value', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.create_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_create_serving_config_rest_required_fields(request_type=serving_config_service.CreateServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["serving_config_id"] = "" + 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 + assert "servingConfigId" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_serving_config._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "servingConfigId" in jsonified_request + assert jsonified_request["servingConfigId"] == request_init["serving_config_id"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["servingConfigId"] = 'serving_config_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).create_serving_config._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("serving_config_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' + assert "servingConfigId" in jsonified_request + assert jsonified_request["servingConfigId"] == 'serving_config_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.create_serving_config(request) + + expected_params = [ + ( + "servingConfigId", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_create_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.create_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("servingConfigId", )) & set(("parent", "servingConfig", "servingConfigId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_create_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_create_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_create_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.CreateServingConfigRequest.pb(serving_config_service.CreateServingConfigRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.CreateServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.create_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_create_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.CreateServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["serving_config"] = {'name': 'name_value', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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_serving_config(request) + + +def test_create_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + + # get truthy value for each flattened field + mock_args = dict( + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.create_serving_config(**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/v2beta/{parent=projects/*/locations/*/catalogs/*}/servingConfigs" % client.transport._host, args[1]) + + +def test_create_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.CreateServingConfigRequest(), + parent='parent_value', + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + serving_config_id='serving_config_id_value', + ) + + +def test_create_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.DeleteServingConfigRequest, + dict, +]) +def test_delete_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + # Establish that the response is the type that we expect. + assert response is None + + +def test_delete_serving_config_rest_required_fields(request_type=serving_config_service.DeleteServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + 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_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_delete_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.delete_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_delete_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "pre_delete_serving_config") as pre: + pre.assert_not_called() + pb_message = serving_config_service.DeleteServingConfigRequest.pb(serving_config_service.DeleteServingConfigRequest()) + 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 = serving_config_service.DeleteServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + + client.delete_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + + +def test_delete_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.DeleteServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + +def test_delete_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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/catalogs/sample3/servingConfigs/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_serving_config(**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/v2beta/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_delete_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.DeleteServingConfigRequest(), + name='name_value', + ) + + +def test_delete_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.UpdateServingConfigRequest, + dict, +]) +def test_update_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + request_init["serving_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.update_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_update_serving_config_rest_required_fields(request_type=serving_config_service.UpdateServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.update_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_update_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.update_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(("updateMask", )) & set(("servingConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_update_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_update_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_update_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.UpdateServingConfigRequest.pb(serving_config_service.UpdateServingConfigRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.UpdateServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.update_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_update_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.UpdateServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + request_init["serving_config"] = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4', 'display_name': 'display_name_value', 'model_id': 'model_id_value', 'price_reranking_level': 'price_reranking_level_value', 'facet_control_ids': ['facet_control_ids_value1', 'facet_control_ids_value2'], 'dynamic_facet_spec': {'mode': 1}, 'boost_control_ids': ['boost_control_ids_value1', 'boost_control_ids_value2'], 'filter_control_ids': ['filter_control_ids_value1', 'filter_control_ids_value2'], 'redirect_control_ids': ['redirect_control_ids_value1', 'redirect_control_ids_value2'], 'twoway_synonyms_control_ids': ['twoway_synonyms_control_ids_value1', 'twoway_synonyms_control_ids_value2'], 'oneway_synonyms_control_ids': ['oneway_synonyms_control_ids_value1', 'oneway_synonyms_control_ids_value2'], 'do_not_associate_control_ids': ['do_not_associate_control_ids_value1', 'do_not_associate_control_ids_value2'], 'replacement_control_ids': ['replacement_control_ids_value1', 'replacement_control_ids_value2'], 'ignore_control_ids': ['ignore_control_ids_value1', 'ignore_control_ids_value2'], 'diversity_level': 'diversity_level_value', 'diversity_type': 2, 'enable_category_filter_level': 'enable_category_filter_level_value', 'personalization_spec': {'mode': 1}, 'solution_types': [1]} + 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_serving_config(request) + + +def test_update_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'}} + + # get truthy value for each flattened field + mock_args = dict( + serving_config=gcr_serving_config.ServingConfig(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 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.update_serving_config(**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/v2beta/{serving_config.name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_update_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.UpdateServingConfigRequest(), + serving_config=gcr_serving_config.ServingConfig(name='name_value'), + update_mask=field_mask_pb2.FieldMask(paths=['paths_value']), + ) + + +def test_update_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.GetServingConfigRequest, + dict, +]) +def test_get_serving_config_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.get_serving_config(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_get_serving_config_rest_required_fields(request_type=serving_config_service.GetServingConfigRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_config._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_serving_config._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = serving_config.ServingConfig() + # 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 + + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.get_serving_config(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_get_serving_config_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.get_serving_config._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("name", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_get_serving_config_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_get_serving_config") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_get_serving_config") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.GetServingConfigRequest.pb(serving_config_service.GetServingConfigRequest()) + 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 = serving_config.ServingConfig.to_json(serving_config.ServingConfig()) + + request = serving_config_service.GetServingConfigRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = serving_config.ServingConfig() + + client.get_serving_config(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_get_serving_config_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.GetServingConfigRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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_serving_config(request) + + +def test_get_serving_config_rest_flattened(): + client = ServingConfigServiceClient( + 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 = serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 + pb_return_value = serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.get_serving_config(**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/v2beta/{name=projects/*/locations/*/catalogs/*/servingConfigs/*}" % client.transport._host, args[1]) + + +def test_get_serving_config_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_config( + serving_config_service.GetServingConfigRequest(), + name='name_value', + ) + + +def test_get_serving_config_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.ListServingConfigsRequest, + dict, +]) +def test_list_serving_configs_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = serving_config_service.ListServingConfigsResponse( + next_page_token='next_page_token_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.list_serving_configs(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, pagers.ListServingConfigsPager) + assert response.next_page_token == 'next_page_token_value' + + +def test_list_serving_configs_rest_required_fields(request_type=serving_config_service.ListServingConfigsRequest): + transport_class = transports.ServingConfigServiceRestTransport + + 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_serving_configs._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_serving_configs._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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = serving_config_service.ListServingConfigsResponse() + # 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 + + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.list_serving_configs(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_list_serving_configs_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.list_serving_configs._get_unset_required_fields({}) + assert set(unset_fields) == (set(("pageSize", "pageToken", )) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_list_serving_configs_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_list_serving_configs") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_list_serving_configs") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.ListServingConfigsRequest.pb(serving_config_service.ListServingConfigsRequest()) + 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 = serving_config_service.ListServingConfigsResponse.to_json(serving_config_service.ListServingConfigsResponse()) + + request = serving_config_service.ListServingConfigsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = serving_config_service.ListServingConfigsResponse() + + client.list_serving_configs(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_list_serving_configs_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.ListServingConfigsRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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_serving_configs(request) + + +def test_list_serving_configs_rest_flattened(): + client = ServingConfigServiceClient( + 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 = serving_config_service.ListServingConfigsResponse() + + # get arguments that satisfy an http rule for this method + sample_request = {'parent': 'projects/sample1/locations/sample2/catalogs/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 + pb_return_value = serving_config_service.ListServingConfigsResponse.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.list_serving_configs(**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/v2beta/{parent=projects/*/locations/*/catalogs/*}/servingConfigs" % client.transport._host, args[1]) + + +def test_list_serving_configs_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_serving_configs( + serving_config_service.ListServingConfigsRequest(), + parent='parent_value', + ) + + +def test_list_serving_configs_rest_pager(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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 = ( + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + next_page_token='abc', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[], + next_page_token='def', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + ], + next_page_token='ghi', + ), + serving_config_service.ListServingConfigsResponse( + serving_configs=[ + serving_config.ServingConfig(), + serving_config.ServingConfig(), + ], + ), + ) + # Two responses for two calls + response = response + response + + # Wrap the values into proper Response objs + response = tuple(serving_config_service.ListServingConfigsResponse.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/catalogs/sample3'} + + pager = client.list_serving_configs(request=sample_request) + + results = list(pager) + assert len(results) == 6 + assert all(isinstance(i, serving_config.ServingConfig) + for i in results) + + pages = list(client.list_serving_configs(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", [ + serving_config_service.AddControlRequest, + dict, +]) +def test_add_control_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.add_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_add_control_rest_required_fields(request_type=serving_config_service.AddControlRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["serving_config"] = "" + request_init["control_id"] = "" + 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_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["servingConfig"] = 'serving_config_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).add_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "servingConfig" in jsonified_request + assert jsonified_request["servingConfig"] == 'serving_config_value' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.add_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_add_control_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.add_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("servingConfig", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_add_control_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_add_control") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_add_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.AddControlRequest.pb(serving_config_service.AddControlRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.AddControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.add_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_add_control_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.AddControlRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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.add_control(request) + + +def test_add_control_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + serving_config='serving_config_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.add_control(**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/v2beta/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:addControl" % client.transport._host, args[1]) + + +def test_add_control_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.AddControlRequest(), + serving_config='serving_config_value', + ) + + +def test_add_control_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + serving_config_service.RemoveControlRequest, + dict, +]) +def test_remove_control_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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 = gcr_serving_config.ServingConfig( + name='name_value', + display_name='display_name_value', + model_id='model_id_value', + price_reranking_level='price_reranking_level_value', + facet_control_ids=['facet_control_ids_value'], + boost_control_ids=['boost_control_ids_value'], + filter_control_ids=['filter_control_ids_value'], + redirect_control_ids=['redirect_control_ids_value'], + twoway_synonyms_control_ids=['twoway_synonyms_control_ids_value'], + oneway_synonyms_control_ids=['oneway_synonyms_control_ids_value'], + do_not_associate_control_ids=['do_not_associate_control_ids_value'], + replacement_control_ids=['replacement_control_ids_value'], + ignore_control_ids=['ignore_control_ids_value'], + diversity_level='diversity_level_value', + diversity_type=gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY, + enable_category_filter_level='enable_category_filter_level_value', + solution_types=[common.SolutionType.SOLUTION_TYPE_RECOMMENDATION], + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.remove_control(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, gcr_serving_config.ServingConfig) + assert response.name == 'name_value' + assert response.display_name == 'display_name_value' + assert response.model_id == 'model_id_value' + assert response.price_reranking_level == 'price_reranking_level_value' + assert response.facet_control_ids == ['facet_control_ids_value'] + assert response.boost_control_ids == ['boost_control_ids_value'] + assert response.filter_control_ids == ['filter_control_ids_value'] + assert response.redirect_control_ids == ['redirect_control_ids_value'] + assert response.twoway_synonyms_control_ids == ['twoway_synonyms_control_ids_value'] + assert response.oneway_synonyms_control_ids == ['oneway_synonyms_control_ids_value'] + assert response.do_not_associate_control_ids == ['do_not_associate_control_ids_value'] + assert response.replacement_control_ids == ['replacement_control_ids_value'] + assert response.ignore_control_ids == ['ignore_control_ids_value'] + assert response.diversity_level == 'diversity_level_value' + assert response.diversity_type == gcr_serving_config.ServingConfig.DiversityType.RULE_BASED_DIVERSITY + assert response.enable_category_filter_level == 'enable_category_filter_level_value' + assert response.solution_types == [common.SolutionType.SOLUTION_TYPE_RECOMMENDATION] + + +def test_remove_control_rest_required_fields(request_type=serving_config_service.RemoveControlRequest): + transport_class = transports.ServingConfigServiceRestTransport + + request_init = {} + request_init["serving_config"] = "" + request_init["control_id"] = "" + 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_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + + jsonified_request["servingConfig"] = 'serving_config_value' + jsonified_request["controlId"] = 'control_id_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).remove_control._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with non-default values are left alone + assert "servingConfig" in jsonified_request + assert jsonified_request["servingConfig"] == 'serving_config_value' + assert "controlId" in jsonified_request + assert jsonified_request["controlId"] == 'control_id_value' + + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = gcr_serving_config.ServingConfig() + # 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 + + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.remove_control(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_remove_control_rest_unset_required_fields(): + transport = transports.ServingConfigServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.remove_control._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("servingConfig", "controlId", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_remove_control_rest_interceptors(null_interceptor): + transport = transports.ServingConfigServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.ServingConfigServiceRestInterceptor(), + ) + client = ServingConfigServiceClient(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.ServingConfigServiceRestInterceptor, "post_remove_control") as post, \ + mock.patch.object(transports.ServingConfigServiceRestInterceptor, "pre_remove_control") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = serving_config_service.RemoveControlRequest.pb(serving_config_service.RemoveControlRequest()) + 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 = gcr_serving_config.ServingConfig.to_json(gcr_serving_config.ServingConfig()) + + request = serving_config_service.RemoveControlRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = gcr_serving_config.ServingConfig() + + client.remove_control(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_remove_control_rest_bad_request(transport: str = 'rest', request_type=serving_config_service.RemoveControlRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/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.remove_control(request) + + +def test_remove_control_rest_flattened(): + client = ServingConfigServiceClient( + 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 = gcr_serving_config.ServingConfig() + + # get arguments that satisfy an http rule for this method + sample_request = {'serving_config': 'projects/sample1/locations/sample2/catalogs/sample3/servingConfigs/sample4'} + + # get truthy value for each flattened field + mock_args = dict( + serving_config='serving_config_value', + ) + mock_args.update(sample_request) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = gcr_serving_config.ServingConfig.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + client.remove_control(**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/v2beta/{serving_config=projects/*/locations/*/catalogs/*/servingConfigs/*}:removeControl" % client.transport._host, args[1]) + + +def test_remove_control_rest_flattened_error(transport: str = 'rest'): + client = ServingConfigServiceClient( + 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_control( + serving_config_service.RemoveControlRequest(), + serving_config='serving_config_value', + ) + + +def test_remove_control_rest_error(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + 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 = ServingConfigServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = ServingConfigServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = ServingConfigServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.ServingConfigServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.ServingConfigServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + transports.ServingConfigServiceRestTransport, +]) +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 = ServingConfigServiceClient.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 = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.ServingConfigServiceGrpcTransport, + ) + +def test_serving_config_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.ServingConfigServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_serving_config_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.serving_config_service.transports.ServingConfigServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.ServingConfigServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'create_serving_config', + 'delete_serving_config', + 'update_serving_config', + 'get_serving_config', + 'list_serving_configs', + 'add_control', + 'remove_control', + 'get_operation', + 'list_operations', + ) + 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_serving_config_service_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.retail_v2beta.services.serving_config_service.transports.ServingConfigServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServingConfigServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_serving_config_service_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.retail_v2beta.services.serving_config_service.transports.ServingConfigServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.ServingConfigServiceTransport() + adc.assert_called_once() + + +def test_serving_config_service_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) + ServingConfigServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + ], +) +def test_serving_config_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.ServingConfigServiceGrpcTransport, + transports.ServingConfigServiceGrpcAsyncIOTransport, + transports.ServingConfigServiceRestTransport, + ], +) +def test_serving_config_service_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.ServingConfigServiceGrpcTransport, grpc_helpers), + (transports.ServingConfigServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_serving_config_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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_serving_config_service_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.ServingConfigServiceRestTransport ( + 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_serving_config_service_host_no_port(transport_name): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_serving_config_service_host_with_port(transport_name): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_serving_config_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = ServingConfigServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = ServingConfigServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.create_serving_config._session + session2 = client2.transport.create_serving_config._session + assert session1 != session2 + session1 = client1.transport.delete_serving_config._session + session2 = client2.transport.delete_serving_config._session + assert session1 != session2 + session1 = client1.transport.update_serving_config._session + session2 = client2.transport.update_serving_config._session + assert session1 != session2 + session1 = client1.transport.get_serving_config._session + session2 = client2.transport.get_serving_config._session + assert session1 != session2 + session1 = client1.transport.list_serving_configs._session + session2 = client2.transport.list_serving_configs._session + assert session1 != session2 + session1 = client1.transport.add_control._session + session2 = client2.transport.add_control._session + assert session1 != session2 + session1 = client1.transport.remove_control._session + session2 = client2.transport.remove_control._session + assert session1 != session2 +def test_serving_config_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ServingConfigServiceGrpcTransport( + 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_serving_config_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.ServingConfigServiceGrpcAsyncIOTransport( + 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.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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.ServingConfigServiceGrpcTransport, transports.ServingConfigServiceGrpcAsyncIOTransport]) +def test_serving_config_service_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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = ServingConfigServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = ServingConfigServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_serving_config_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + serving_config = "nautilus" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/servingConfigs/{serving_config}".format(project=project, location=location, catalog=catalog, serving_config=serving_config, ) + actual = ServingConfigServiceClient.serving_config_path(project, location, catalog, serving_config) + assert expected == actual + + +def test_parse_serving_config_path(): + expected = { + "project": "scallop", + "location": "abalone", + "catalog": "squid", + "serving_config": "clam", + } + path = ServingConfigServiceClient.serving_config_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_serving_config_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "whelk" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = ServingConfigServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "octopus", + } + path = ServingConfigServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "oyster" + expected = "folders/{folder}".format(folder=folder, ) + actual = ServingConfigServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "nudibranch", + } + path = ServingConfigServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "cuttlefish" + expected = "organizations/{organization}".format(organization=organization, ) + actual = ServingConfigServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "mussel", + } + path = ServingConfigServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "winkle" + expected = "projects/{project}".format(project=project, ) + actual = ServingConfigServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "nautilus", + } + path = ServingConfigServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "scallop" + location = "abalone" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = ServingConfigServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "squid", + "location": "clam", + } + path = ServingConfigServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = ServingConfigServiceClient.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.ServingConfigServiceTransport, '_prep_wrapped_messages') as prep: + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.ServingConfigServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = ServingConfigServiceClient.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 = ServingConfigServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = ServingConfigServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = ServingConfigServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = ServingConfigServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = ServingConfigServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = ServingConfigServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = ServingConfigServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = ServingConfigServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = ServingConfigServiceClient( + 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 = ServingConfigServiceClient( + 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", [ + (ServingConfigServiceClient, transports.ServingConfigServiceGrpcTransport), + (ServingConfigServiceAsyncClient, transports.ServingConfigServiceGrpcAsyncIOTransport), +]) +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/v2beta/tests/unit/gapic/retail_v2beta/test_user_event_service.py b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_user_event_service.py new file mode 100644 index 00000000..56a8f26a --- /dev/null +++ b/owl-bot-staging/v2beta/tests/unit/gapic/retail_v2beta/test_user_event_service.py @@ -0,0 +1,3431 @@ +# -*- coding: utf-8 -*- +# Copyright 2023 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT 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 import httpbody_pb2 # type: ignore +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.location import locations_pb2 +from google.cloud.retail_v2beta.services.user_event_service import UserEventServiceAsyncClient +from google.cloud.retail_v2beta.services.user_event_service import UserEventServiceClient +from google.cloud.retail_v2beta.services.user_event_service import transports +from google.cloud.retail_v2beta.types import common +from google.cloud.retail_v2beta.types import import_config +from google.cloud.retail_v2beta.types import product +from google.cloud.retail_v2beta.types import promotion +from google.cloud.retail_v2beta.types import purge_config +from google.cloud.retail_v2beta.types import user_event +from google.cloud.retail_v2beta.types import user_event_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 duration_pb2 # type: ignore +from google.protobuf import field_mask_pb2 # type: ignore +from google.protobuf import timestamp_pb2 # type: ignore +from google.protobuf import wrappers_pb2 # type: ignore +from google.type import date_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 UserEventServiceClient._get_default_mtls_endpoint(None) is None + assert UserEventServiceClient._get_default_mtls_endpoint(api_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(api_mtls_endpoint) == api_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(sandbox_mtls_endpoint) == sandbox_mtls_endpoint + assert UserEventServiceClient._get_default_mtls_endpoint(non_googleapi) == non_googleapi + + +@pytest.mark.parametrize("client_class,transport_name", [ + (UserEventServiceClient, "grpc"), + (UserEventServiceAsyncClient, "grpc_asyncio"), + (UserEventServiceClient, "rest"), +]) +def test_user_event_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +@pytest.mark.parametrize("transport_class,transport_name", [ + (transports.UserEventServiceGrpcTransport, "grpc"), + (transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (transports.UserEventServiceRestTransport, "rest"), +]) +def test_user_event_service_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", [ + (UserEventServiceClient, "grpc"), + (UserEventServiceAsyncClient, "grpc_asyncio"), + (UserEventServiceClient, "rest"), +]) +def test_user_event_service_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 == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else + 'https://retail.googleapis.com' + ) + + +def test_user_event_service_client_get_transport_class(): + transport = UserEventServiceClient.get_transport_class() + available_transports = [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceRestTransport, + ] + assert transport in available_transports + + transport = UserEventServiceClient.get_transport_class("grpc") + assert transport == transports.UserEventServiceGrpcTransport + + +@pytest.mark.parametrize("client_class,transport_class,transport_name", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_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(UserEventServiceClient, '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(UserEventServiceClient, '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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "true"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "true"), + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", "false"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", "false"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", "true"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", "false"), +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +@mock.patch.dict(os.environ, {"GOOGLE_API_USE_MTLS_ENDPOINT": "auto"}) +def test_user_event_service_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", [ + UserEventServiceClient, UserEventServiceAsyncClient +]) +@mock.patch.object(UserEventServiceClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceClient)) +@mock.patch.object(UserEventServiceAsyncClient, "DEFAULT_ENDPOINT", modify_default_endpoint(UserEventServiceAsyncClient)) +def test_user_event_service_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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc"), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio"), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest"), +]) +def test_user_event_service_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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", grpc_helpers), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), + (UserEventServiceClient, transports.UserEventServiceRestTransport, "rest", None), +]) +def test_user_event_service_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_user_event_service_client_client_options_from_dict(): + with mock.patch('google.cloud.retail_v2beta.services.user_event_service.transports.UserEventServiceGrpcTransport.__init__') as grpc_transport: + grpc_transport.return_value = None + client = UserEventServiceClient( + 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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport, "grpc", grpc_helpers), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport, "grpc_asyncio", grpc_helpers_async), +]) +def test_user_event_service_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( + "retail.googleapis.com:443", + credentials=file_creds, + credentials_file=None, + quota_project_id=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=None, + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.WriteUserEventRequest, + dict, +]) +def test_write_user_event(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + ) + response = client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +def test_write_user_event_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 = UserEventServiceClient( + 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.write_user_event), + '__call__') as call: + client.write_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + +@pytest.mark.asyncio +async def test_write_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.WriteUserEventRequest): + client = UserEventServiceAsyncClient( + 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.write_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + )) + response = await client.write_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.WriteUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +@pytest.mark.asyncio +async def test_write_user_event_async_from_dict(): + await test_write_user_event_async(request_type=dict) + + +def test_write_user_event_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.WriteUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = user_event.UserEvent() + client.write_user_event(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_write_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.WriteUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.write_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(user_event.UserEvent()) + await client.write_user_event(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.CollectUserEventRequest, + dict, +]) +def test_collect_user_event(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.collect_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + ) + response = client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +def test_collect_user_event_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 = UserEventServiceClient( + 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.collect_user_event), + '__call__') as call: + client.collect_user_event() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + +@pytest.mark.asyncio +async def test_collect_user_event_async(transport: str = 'grpc_asyncio', request_type=user_event_service.CollectUserEventRequest): + client = UserEventServiceAsyncClient( + 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.collect_user_event), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value =grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + )) + response = await client.collect_user_event(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.CollectUserEventRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +@pytest.mark.asyncio +async def test_collect_user_event_async_from_dict(): + await test_collect_user_event_async(request_type=dict) + + +def test_collect_user_event_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.CollectUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = httpbody_pb2.HttpBody() + client.collect_user_event(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_collect_user_event_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.CollectUserEventRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.collect_user_event), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(httpbody_pb2.HttpBody()) + await client.collect_user_event(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'] + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeUserEventsRequest, + dict, +]) +def test_purge_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.purge_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_purge_user_events_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 = UserEventServiceClient( + 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_user_events), + '__call__') as call: + client.purge_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + +@pytest.mark.asyncio +async def test_purge_user_events_async(transport: str = 'grpc_asyncio', request_type=purge_config.PurgeUserEventsRequest): + client = UserEventServiceAsyncClient( + 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_user_events), + '__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_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == purge_config.PurgeUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_purge_user_events_async_from_dict(): + await test_purge_user_events_async(request_type=dict) + + +def test_purge_user_events_field_headers(): + client = UserEventServiceClient( + 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 = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.purge_user_events(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_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = purge_config.PurgeUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.purge_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.purge_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportUserEventsRequest, + dict, +]) +def test_import_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.import_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_import_user_events_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 = UserEventServiceClient( + 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_user_events), + '__call__') as call: + client.import_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + +@pytest.mark.asyncio +async def test_import_user_events_async(transport: str = 'grpc_asyncio', request_type=import_config.ImportUserEventsRequest): + client = UserEventServiceAsyncClient( + 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_user_events), + '__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_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == import_config.ImportUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_import_user_events_async_from_dict(): + await test_import_user_events_async(request_type=dict) + + +def test_import_user_events_field_headers(): + client = UserEventServiceClient( + 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 = import_config.ImportUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.import_user_events(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_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = import_config.ImportUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.import_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.import_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.RejoinUserEventsRequest, + dict, +]) +def test_rejoin_user_events(request_type, transport: str = 'grpc'): + client = UserEventServiceClient( + 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.rejoin_user_events), + '__call__') as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation(name='operations/spam') + response = client.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) == 1 + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +def test_rejoin_user_events_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 = UserEventServiceClient( + 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.rejoin_user_events), + '__call__') as call: + client.rejoin_user_events() + call.assert_called() + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + +@pytest.mark.asyncio +async def test_rejoin_user_events_async(transport: str = 'grpc_asyncio', request_type=user_event_service.RejoinUserEventsRequest): + client = UserEventServiceAsyncClient( + 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.rejoin_user_events), + '__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.rejoin_user_events(request) + + # Establish that the underlying gRPC stub method was called. + assert len(call.mock_calls) + _, args, _ = call.mock_calls[0] + assert args[0] == user_event_service.RejoinUserEventsRequest() + + # Establish that the response is the type that we expect. + assert isinstance(response, future.Future) + + +@pytest.mark.asyncio +async def test_rejoin_user_events_async_from_dict(): + await test_rejoin_user_events_async(request_type=dict) + + +def test_rejoin_user_events_field_headers(): + client = UserEventServiceClient( + 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 = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = operations_pb2.Operation(name='operations/op') + client.rejoin_user_events(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_rejoin_user_events_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = user_event_service.RejoinUserEventsRequest() + + request.parent = 'parent_value' + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object( + type(client.transport.rejoin_user_events), + '__call__') as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall(operations_pb2.Operation(name='operations/op')) + await client.rejoin_user_events(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'] + + +@pytest.mark.parametrize("request_type", [ + user_event_service.WriteUserEventRequest, + dict, +]) +def test_write_user_event_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["user_event"] = {'event_type': 'event_type_value', 'visitor_id': 'visitor_id_value', 'session_id': 'session_id_value', 'event_time': {'seconds': 751, 'nanos': 543}, 'experiment_ids': ['experiment_ids_value1', 'experiment_ids_value2'], 'attribution_token': 'attribution_token_value', 'product_details': [{'product': {'expire_time': {}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]}, 'quantity': {}}], 'completion_detail': {'completion_attribution_token': 'completion_attribution_token_value', 'selected_suggestion': 'selected_suggestion_value', 'selected_position': 1821}, 'attributes': {}, 'cart_id': 'cart_id_value', 'purchase_transaction': {'id': 'id_value', 'revenue': 0.762, 'tax': 0.333, 'cost': 0.441, 'currency_code': 'currency_code_value'}, 'search_query': 'search_query_value', 'filter': 'filter_value', 'order_by': 'order_by_value', 'offset': 647, 'page_categories': ['page_categories_value1', 'page_categories_value2'], 'user_info': {'user_id': 'user_id_value', 'ip_address': 'ip_address_value', 'user_agent': 'user_agent_value', 'direct_user_request': True}, 'uri': 'uri_value', 'referrer_uri': 'referrer_uri_value', 'page_view_id': 'page_view_id_value', 'entity': 'entity_value'} + 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 = user_event.UserEvent( + event_type='event_type_value', + visitor_id='visitor_id_value', + session_id='session_id_value', + experiment_ids=['experiment_ids_value'], + attribution_token='attribution_token_value', + cart_id='cart_id_value', + search_query='search_query_value', + filter='filter_value', + order_by='order_by_value', + offset=647, + page_categories=['page_categories_value'], + uri='uri_value', + referrer_uri='referrer_uri_value', + page_view_id='page_view_id_value', + entity='entity_value', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = user_event.UserEvent.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.write_user_event(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, user_event.UserEvent) + assert response.event_type == 'event_type_value' + assert response.visitor_id == 'visitor_id_value' + assert response.session_id == 'session_id_value' + assert response.experiment_ids == ['experiment_ids_value'] + assert response.attribution_token == 'attribution_token_value' + assert response.cart_id == 'cart_id_value' + assert response.search_query == 'search_query_value' + assert response.filter == 'filter_value' + assert response.order_by == 'order_by_value' + assert response.offset == 647 + assert response.page_categories == ['page_categories_value'] + assert response.uri == 'uri_value' + assert response.referrer_uri == 'referrer_uri_value' + assert response.page_view_id == 'page_view_id_value' + assert response.entity == 'entity_value' + + +def test_write_user_event_rest_required_fields(request_type=user_event_service.WriteUserEventRequest): + transport_class = transports.UserEventServiceRestTransport + + 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()).write_user_event._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()).write_user_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("write_async", )) + 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 = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = user_event.UserEvent() + # 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 + + pb_return_value = user_event.UserEvent.pb(return_value) + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.write_user_event(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_write_user_event_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.write_user_event._get_unset_required_fields({}) + assert set(unset_fields) == (set(("writeAsync", )) & set(("parent", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_write_user_event_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_write_user_event") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_write_user_event") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.WriteUserEventRequest.pb(user_event_service.WriteUserEventRequest()) + 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 = user_event.UserEvent.to_json(user_event.UserEvent()) + + request = user_event_service.WriteUserEventRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = user_event.UserEvent() + + client.write_user_event(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_write_user_event_rest_bad_request(transport: str = 'rest', request_type=user_event_service.WriteUserEventRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/sample3'} + request_init["user_event"] = {'event_type': 'event_type_value', 'visitor_id': 'visitor_id_value', 'session_id': 'session_id_value', 'event_time': {'seconds': 751, 'nanos': 543}, 'experiment_ids': ['experiment_ids_value1', 'experiment_ids_value2'], 'attribution_token': 'attribution_token_value', 'product_details': [{'product': {'expire_time': {}, 'ttl': {'seconds': 751, 'nanos': 543}, 'name': 'name_value', 'id': 'id_value', 'type_': 1, 'primary_product_id': 'primary_product_id_value', 'collection_member_ids': ['collection_member_ids_value1', 'collection_member_ids_value2'], 'gtin': 'gtin_value', 'categories': ['categories_value1', 'categories_value2'], 'title': 'title_value', 'brands': ['brands_value1', 'brands_value2'], 'description': 'description_value', 'language_code': 'language_code_value', 'attributes': {}, 'tags': ['tags_value1', 'tags_value2'], 'price_info': {'currency_code': 'currency_code_value', 'price': 0.531, 'original_price': 0.1479, 'cost': 0.441, 'price_effective_time': {}, 'price_expire_time': {}, 'price_range': {'price': {'minimum': 0.764, 'exclusive_minimum': 0.18430000000000002, 'maximum': 0.766, 'exclusive_maximum': 0.1845}, 'original_price': {}}}, 'rating': {'rating_count': 1293, 'average_rating': 0.1471, 'rating_histogram': [1715, 1716]}, 'available_time': {}, 'availability': 1, 'available_quantity': {'value': 541}, 'fulfillment_info': [{'type_': 'type__value', 'place_ids': ['place_ids_value1', 'place_ids_value2']}], 'uri': 'uri_value', 'images': [{'uri': 'uri_value', 'height': 633, 'width': 544}], 'audience': {'genders': ['genders_value1', 'genders_value2'], 'age_groups': ['age_groups_value1', 'age_groups_value2']}, 'color_info': {'color_families': ['color_families_value1', 'color_families_value2'], 'colors': ['colors_value1', 'colors_value2']}, 'sizes': ['sizes_value1', 'sizes_value2'], 'materials': ['materials_value1', 'materials_value2'], 'patterns': ['patterns_value1', 'patterns_value2'], 'conditions': ['conditions_value1', 'conditions_value2'], 'promotions': [{'promotion_id': 'promotion_id_value'}], 'publish_time': {}, 'retrievable_fields': {'paths': ['paths_value1', 'paths_value2']}, 'variants': {}, 'local_inventories': [{'place_id': 'place_id_value', 'price_info': {}, 'attributes': {}, 'fulfillment_types': ['fulfillment_types_value1', 'fulfillment_types_value2']}]}, 'quantity': {}}], 'completion_detail': {'completion_attribution_token': 'completion_attribution_token_value', 'selected_suggestion': 'selected_suggestion_value', 'selected_position': 1821}, 'attributes': {}, 'cart_id': 'cart_id_value', 'purchase_transaction': {'id': 'id_value', 'revenue': 0.762, 'tax': 0.333, 'cost': 0.441, 'currency_code': 'currency_code_value'}, 'search_query': 'search_query_value', 'filter': 'filter_value', 'order_by': 'order_by_value', 'offset': 647, 'page_categories': ['page_categories_value1', 'page_categories_value2'], 'user_info': {'user_id': 'user_id_value', 'ip_address': 'ip_address_value', 'user_agent': 'user_agent_value', 'direct_user_request': True}, 'uri': 'uri_value', 'referrer_uri': 'referrer_uri_value', 'page_view_id': 'page_view_id_value', 'entity': 'entity_value'} + 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.write_user_event(request) + + +def test_write_user_event_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.CollectUserEventRequest, + dict, +]) +def test_collect_user_event_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = httpbody_pb2.HttpBody( + content_type='content_type_value', + data=b'data_blob', + ) + + # Wrap the value into a proper Response obj + response_value = Response() + response_value.status_code = 200 + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + response = client.collect_user_event(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, httpbody_pb2.HttpBody) + assert response.content_type == 'content_type_value' + assert response.data == b'data_blob' + + +def test_collect_user_event_rest_required_fields(request_type=user_event_service.CollectUserEventRequest): + transport_class = transports.UserEventServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["user_event"] = "" + 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 + assert "userEvent" not in jsonified_request + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).collect_user_event._get_unset_required_fields(jsonified_request) + jsonified_request.update(unset_fields) + + # verify required fields with default values are now present + assert "userEvent" in jsonified_request + assert jsonified_request["userEvent"] == request_init["user_event"] + + jsonified_request["parent"] = 'parent_value' + jsonified_request["userEvent"] = 'user_event_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).collect_user_event._get_unset_required_fields(jsonified_request) + # Check that path parameters and body parameters are not mixing in. + assert not set(unset_fields) - set(("ets", "prebuilt_rule", "raw_json", "uri", "user_event", )) + 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' + assert "userEvent" in jsonified_request + assert jsonified_request["userEvent"] == 'user_event_value' + + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest', + ) + request = request_type(**request_init) + + # Designate an appropriate value for the returned response. + return_value = httpbody_pb2.HttpBody() + # 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 + + pb_return_value = return_value + json_return_value = json_format.MessageToJson(pb_return_value) + + response_value._content = json_return_value.encode('UTF-8') + req.return_value = response_value + + response = client.collect_user_event(request) + + expected_params = [ + ( + "userEvent", + "", + ), + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_collect_user_event_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.collect_user_event._get_unset_required_fields({}) + assert set(unset_fields) == (set(("ets", "prebuiltRule", "rawJson", "uri", "userEvent", )) & set(("parent", "userEvent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_collect_user_event_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_collect_user_event") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_collect_user_event") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.CollectUserEventRequest.pb(user_event_service.CollectUserEventRequest()) + 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(httpbody_pb2.HttpBody()) + + request = user_event_service.CollectUserEventRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = httpbody_pb2.HttpBody() + + client.collect_user_event(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_collect_user_event_rest_bad_request(transport: str = 'rest', request_type=user_event_service.CollectUserEventRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.collect_user_event(request) + + +def test_collect_user_event_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + purge_config.PurgeUserEventsRequest, + dict, +]) +def test_purge_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_purge_user_events_rest_required_fields(request_type=purge_config.PurgeUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + request_init = {} + request_init["parent"] = "" + request_init["filter"] = "" + 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_user_events._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' + jsonified_request["filter"] = 'filter_value' + + unset_fields = transport_class(credentials=ga_credentials.AnonymousCredentials()).purge_user_events._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' + assert "filter" in jsonified_request + assert jsonified_request["filter"] == 'filter_value' + + client = UserEventServiceClient( + 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_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_purge_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.purge_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "filter", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_purge_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_purge_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_purge_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = purge_config.PurgeUserEventsRequest.pb(purge_config.PurgeUserEventsRequest()) + 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 = purge_config.PurgeUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.purge_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_purge_user_events_rest_bad_request(transport: str = 'rest', request_type=purge_config.PurgeUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.purge_user_events(request) + + +def test_purge_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + import_config.ImportUserEventsRequest, + dict, +]) +def test_import_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_import_user_events_rest_required_fields(request_type=import_config.ImportUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + 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_user_events._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_user_events._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 = UserEventServiceClient( + 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_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_import_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.import_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", "inputConfig", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_import_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_import_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_import_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = import_config.ImportUserEventsRequest.pb(import_config.ImportUserEventsRequest()) + 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 = import_config.ImportUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.import_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_import_user_events_rest_bad_request(transport: str = 'rest', request_type=import_config.ImportUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.import_user_events(request) + + +def test_import_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +@pytest.mark.parametrize("request_type", [ + user_event_service.RejoinUserEventsRequest, + dict, +]) +def test_rejoin_user_events_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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 = 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.rejoin_user_events(request) + + # Establish that the response is the type that we expect. + assert response.operation.name == "operations/spam" + + +def test_rejoin_user_events_rest_required_fields(request_type=user_event_service.RejoinUserEventsRequest): + transport_class = transports.UserEventServiceRestTransport + + 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()).rejoin_user_events._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()).rejoin_user_events._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 = UserEventServiceClient( + 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.rejoin_user_events(request) + + expected_params = [ + ('$alt', 'json;enum-encoding=int') + ] + actual_params = req.call_args.kwargs['params'] + assert expected_params == actual_params + + +def test_rejoin_user_events_rest_unset_required_fields(): + transport = transports.UserEventServiceRestTransport(credentials=ga_credentials.AnonymousCredentials) + + unset_fields = transport.rejoin_user_events._get_unset_required_fields({}) + assert set(unset_fields) == (set(()) & set(("parent", ))) + + +@pytest.mark.parametrize("null_interceptor", [True, False]) +def test_rejoin_user_events_rest_interceptors(null_interceptor): + transport = transports.UserEventServiceRestTransport( + credentials=ga_credentials.AnonymousCredentials(), + interceptor=None if null_interceptor else transports.UserEventServiceRestInterceptor(), + ) + client = UserEventServiceClient(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.UserEventServiceRestInterceptor, "post_rejoin_user_events") as post, \ + mock.patch.object(transports.UserEventServiceRestInterceptor, "pre_rejoin_user_events") as pre: + pre.assert_not_called() + post.assert_not_called() + pb_message = user_event_service.RejoinUserEventsRequest.pb(user_event_service.RejoinUserEventsRequest()) + 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 = user_event_service.RejoinUserEventsRequest() + metadata =[ + ("key", "val"), + ("cephalopod", "squid"), + ] + pre.return_value = request, metadata + post.return_value = operations_pb2.Operation() + + client.rejoin_user_events(request, metadata=[("key", "val"), ("cephalopod", "squid"),]) + + pre.assert_called_once() + post.assert_called_once() + + +def test_rejoin_user_events_rest_bad_request(transport: str = 'rest', request_type=user_event_service.RejoinUserEventsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # send a request that will satisfy transcoding + request_init = {'parent': 'projects/sample1/locations/sample2/catalogs/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.rejoin_user_events(request) + + +def test_rejoin_user_events_rest_error(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport='rest' + ) + + +def test_credentials_transport_error(): + # It is an error to provide credentials and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + # It is an error to provide a credentials file and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"credentials_file": "credentials.json"}, + transport=transport, + ) + + # It is an error to provide an api_key and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + options = client_options.ClientOptions() + options.api_key = "api_key" + with pytest.raises(ValueError): + client = UserEventServiceClient( + 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 = UserEventServiceClient( + client_options=options, + credentials=ga_credentials.AnonymousCredentials() + ) + + # It is an error to provide scopes and a transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + with pytest.raises(ValueError): + client = UserEventServiceClient( + client_options={"scopes": ["1", "2"]}, + transport=transport, + ) + + +def test_transport_instance(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + client = UserEventServiceClient(transport=transport) + assert client.transport is transport + +def test_transport_get_channel(): + # A client may be instantiated with a custom transport instance. + transport = transports.UserEventServiceGrpcTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + + transport = transports.UserEventServiceGrpcAsyncIOTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + channel = transport.grpc_channel + assert channel + +@pytest.mark.parametrize("transport_class", [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + transports.UserEventServiceRestTransport, +]) +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 = UserEventServiceClient.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 = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + assert isinstance( + client.transport, + transports.UserEventServiceGrpcTransport, + ) + +def test_user_event_service_base_transport_error(): + # Passing both a credentials object and credentials_file should raise an error + with pytest.raises(core_exceptions.DuplicateCredentialArgs): + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + credentials_file="credentials.json" + ) + + +def test_user_event_service_base_transport(): + # Instantiate the base transport. + with mock.patch('google.cloud.retail_v2beta.services.user_event_service.transports.UserEventServiceTransport.__init__') as Transport: + Transport.return_value = None + transport = transports.UserEventServiceTransport( + credentials=ga_credentials.AnonymousCredentials(), + ) + + # Every method on the transport should just blindly + # raise NotImplementedError. + methods = ( + 'write_user_event', + 'collect_user_event', + 'purge_user_events', + 'import_user_events', + 'rejoin_user_events', + 'get_operation', + 'list_operations', + ) + 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_user_event_service_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.retail_v2beta.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + load_creds.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport( + 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', +), + quota_project_id="octopus", + ) + + +def test_user_event_service_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.retail_v2beta.services.user_event_service.transports.UserEventServiceTransport._prep_wrapped_messages') as Transport: + Transport.return_value = None + adc.return_value = (ga_credentials.AnonymousCredentials(), None) + transport = transports.UserEventServiceTransport() + adc.assert_called_once() + + +def test_user_event_service_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) + UserEventServiceClient() + adc.assert_called_once_with( + scopes=None, + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + quota_project_id=None, + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + ], +) +def test_user_event_service_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',), + quota_project_id="octopus", + ) + + +@pytest.mark.parametrize( + "transport_class", + [ + transports.UserEventServiceGrpcTransport, + transports.UserEventServiceGrpcAsyncIOTransport, + transports.UserEventServiceRestTransport, + ], +) +def test_user_event_service_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.UserEventServiceGrpcTransport, grpc_helpers), + (transports.UserEventServiceGrpcAsyncIOTransport, grpc_helpers_async) + ], +) +def test_user_event_service_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( + "retail.googleapis.com:443", + credentials=creds, + credentials_file=None, + quota_project_id="octopus", + default_scopes=( + 'https://www.googleapis.com/auth/cloud-platform', +), + scopes=["1", "2"], + default_host="retail.googleapis.com", + ssl_credentials=None, + options=[ + ("grpc.max_send_message_length", -1), + ("grpc.max_receive_message_length", -1), + ], + ) + + +@pytest.mark.parametrize("transport_class", [transports.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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_user_event_service_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.UserEventServiceRestTransport ( + 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_user_event_service_rest_lro_client(): + client = UserEventServiceClient( + 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_user_event_service_host_no_port(transport_name): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:443' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com' + ) + +@pytest.mark.parametrize("transport_name", [ + "grpc", + "grpc_asyncio", + "rest", +]) +def test_user_event_service_host_with_port(transport_name): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_options=client_options.ClientOptions(api_endpoint='retail.googleapis.com:8000'), + transport=transport_name, + ) + assert client.transport._host == ( + 'retail.googleapis.com:8000' + if transport_name in ['grpc', 'grpc_asyncio'] + else 'https://retail.googleapis.com:8000' + ) + +@pytest.mark.parametrize("transport_name", [ + "rest", +]) +def test_user_event_service_client_transport_session_collision(transport_name): + creds1 = ga_credentials.AnonymousCredentials() + creds2 = ga_credentials.AnonymousCredentials() + client1 = UserEventServiceClient( + credentials=creds1, + transport=transport_name, + ) + client2 = UserEventServiceClient( + credentials=creds2, + transport=transport_name, + ) + session1 = client1.transport.write_user_event._session + session2 = client2.transport.write_user_event._session + assert session1 != session2 + session1 = client1.transport.collect_user_event._session + session2 = client2.transport.collect_user_event._session + assert session1 != session2 + session1 = client1.transport.purge_user_events._session + session2 = client2.transport.purge_user_events._session + assert session1 != session2 + session1 = client1.transport.import_user_events._session + session2 = client2.transport.import_user_events._session + assert session1 != session2 + session1 = client1.transport.rejoin_user_events._session + session2 = client2.transport.rejoin_user_events._session + assert session1 != session2 +def test_user_event_service_grpc_transport_channel(): + channel = grpc.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcTransport( + 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_user_event_service_grpc_asyncio_transport_channel(): + channel = aio.secure_channel('http://localhost/', grpc.local_channel_credentials()) + + # Check that channel is used if provided. + transport = transports.UserEventServiceGrpcAsyncIOTransport( + 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.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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.UserEventServiceGrpcTransport, transports.UserEventServiceGrpcAsyncIOTransport]) +def test_user_event_service_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_user_event_service_grpc_lro_client(): + client = UserEventServiceClient( + 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_user_event_service_grpc_lro_async_client(): + client = UserEventServiceAsyncClient( + 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_catalog_path(): + project = "squid" + location = "clam" + catalog = "whelk" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}".format(project=project, location=location, catalog=catalog, ) + actual = UserEventServiceClient.catalog_path(project, location, catalog) + assert expected == actual + + +def test_parse_catalog_path(): + expected = { + "project": "octopus", + "location": "oyster", + "catalog": "nudibranch", + } + path = UserEventServiceClient.catalog_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_catalog_path(path) + assert expected == actual + +def test_product_path(): + project = "cuttlefish" + location = "mussel" + catalog = "winkle" + branch = "nautilus" + product = "scallop" + expected = "projects/{project}/locations/{location}/catalogs/{catalog}/branches/{branch}/products/{product}".format(project=project, location=location, catalog=catalog, branch=branch, product=product, ) + actual = UserEventServiceClient.product_path(project, location, catalog, branch, product) + assert expected == actual + + +def test_parse_product_path(): + expected = { + "project": "abalone", + "location": "squid", + "catalog": "clam", + "branch": "whelk", + "product": "octopus", + } + path = UserEventServiceClient.product_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_product_path(path) + assert expected == actual + +def test_common_billing_account_path(): + billing_account = "oyster" + expected = "billingAccounts/{billing_account}".format(billing_account=billing_account, ) + actual = UserEventServiceClient.common_billing_account_path(billing_account) + assert expected == actual + + +def test_parse_common_billing_account_path(): + expected = { + "billing_account": "nudibranch", + } + path = UserEventServiceClient.common_billing_account_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_billing_account_path(path) + assert expected == actual + +def test_common_folder_path(): + folder = "cuttlefish" + expected = "folders/{folder}".format(folder=folder, ) + actual = UserEventServiceClient.common_folder_path(folder) + assert expected == actual + + +def test_parse_common_folder_path(): + expected = { + "folder": "mussel", + } + path = UserEventServiceClient.common_folder_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_folder_path(path) + assert expected == actual + +def test_common_organization_path(): + organization = "winkle" + expected = "organizations/{organization}".format(organization=organization, ) + actual = UserEventServiceClient.common_organization_path(organization) + assert expected == actual + + +def test_parse_common_organization_path(): + expected = { + "organization": "nautilus", + } + path = UserEventServiceClient.common_organization_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_organization_path(path) + assert expected == actual + +def test_common_project_path(): + project = "scallop" + expected = "projects/{project}".format(project=project, ) + actual = UserEventServiceClient.common_project_path(project) + assert expected == actual + + +def test_parse_common_project_path(): + expected = { + "project": "abalone", + } + path = UserEventServiceClient.common_project_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.parse_common_project_path(path) + assert expected == actual + +def test_common_location_path(): + project = "squid" + location = "clam" + expected = "projects/{project}/locations/{location}".format(project=project, location=location, ) + actual = UserEventServiceClient.common_location_path(project, location) + assert expected == actual + + +def test_parse_common_location_path(): + expected = { + "project": "whelk", + "location": "octopus", + } + path = UserEventServiceClient.common_location_path(**expected) + + # Check that the path construction is reversible. + actual = UserEventServiceClient.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.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + client_info=client_info, + ) + prep.assert_called_once_with(client_info) + + with mock.patch.object(transports.UserEventServiceTransport, '_prep_wrapped_messages') as prep: + transport_class = UserEventServiceClient.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 = UserEventServiceAsyncClient( + 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_get_operation_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.GetOperationRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'}, request) + + # 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_operation(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.GetOperationRequest, + dict, +]) +def test_get_operation_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/sample3/branches/sample4/operations/sample5'} + 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() + + # 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.get_operation(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_list_operations_rest_bad_request(transport: str = 'rest', request_type=operations_pb2.ListOperationsRequest): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport=transport, + ) + + request = request_type() + request = json_format.ParseDict({'name': 'projects/sample1/locations/sample2/catalogs/sample3'}, request) + + # 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_operations(request) + +@pytest.mark.parametrize("request_type", [ + operations_pb2.ListOperationsRequest, + dict, +]) +def test_list_operations_rest(request_type): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + transport="rest", + ) + request_init = {'name': 'projects/sample1/locations/sample2/catalogs/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 = operations_pb2.ListOperationsResponse() + + # 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.list_operations(request) + + # Establish that the response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + + +def test_get_operation(transport: str = "grpc"): + client = UserEventServiceClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + response = client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) +@pytest.mark.asyncio +async def test_get_operation_async(transport: str = "grpc"): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation(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 response is the type that we expect. + assert isinstance(response, operations_pb2.Operation) + +def test_get_operation_field_headers(): + client = UserEventServiceClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = operations_pb2.Operation() + + client.get_operation(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_get_operation_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.GetOperationRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + await client.get_operation(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=locations",) in kw["metadata"] + +def test_get_operation_from_dict(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.Operation() + + response = client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_get_operation_from_dict_async(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.get_operation), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.Operation() + ) + response = await client.get_operation( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_list_operations(transport: str = "grpc"): + client = UserEventServiceClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + response = client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) +@pytest.mark.asyncio +async def test_list_operations_async(transport: str = "grpc"): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations(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 response is the type that we expect. + assert isinstance(response, operations_pb2.ListOperationsResponse) + +def test_list_operations_field_headers(): + client = UserEventServiceClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = operations_pb2.ListOperationsResponse() + + client.list_operations(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=locations",) in kw["metadata"] +@pytest.mark.asyncio +async def test_list_operations_field_headers_async(): + client = UserEventServiceAsyncClient( + 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 = operations_pb2.ListOperationsRequest() + request.name = "locations" + + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + await client.list_operations(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=locations",) in kw["metadata"] + +def test_list_operations_from_dict(): + client = UserEventServiceClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = operations_pb2.ListOperationsResponse() + + response = client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() +@pytest.mark.asyncio +async def test_list_operations_from_dict_async(): + client = UserEventServiceAsyncClient( + credentials=ga_credentials.AnonymousCredentials(), + ) + # Mock the actual call within the gRPC stub, and fake the request. + with mock.patch.object(type(client.transport.list_operations), "__call__") as call: + # Designate an appropriate return value for the call. + call.return_value = grpc_helpers_async.FakeUnaryUnaryCall( + operations_pb2.ListOperationsResponse() + ) + response = await client.list_operations( + request={ + "name": "locations", + } + ) + call.assert_called() + + +def test_transport_close(): + transports = { + "rest": "_session", + "grpc": "_grpc_channel", + } + + for transport, close_name in transports.items(): + client = UserEventServiceClient( + 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 = UserEventServiceClient( + 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", [ + (UserEventServiceClient, transports.UserEventServiceGrpcTransport), + (UserEventServiceAsyncClient, transports.UserEventServiceGrpcAsyncIOTransport), +]) +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, + )